<?php


namespace app\api\controller;

class MemberApp extends ApiBase
{
	public function login()
	{
		$validate = \think\Validate::make(["account" => "require", "password" => "require"], ["account.require" => "账号 不能为空！", "password.require" => "密码 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		$user = \think\Db::name("app_member_user")->where([["appid", "=", $this->project["id"]], ["", "exp", \think\Db::raw("account = '{$this->input["account"]}' or phone='{$this->input["account"]}' or mail='{$this->input["account"]}'")]])->find();
		if (empty($user) || $user["password"] != GeneratePassword($this->input["password"])) {
			$this->response(10156, "用户名或密码错误不存在");
		}
		if ($user["disable"] == 1) {
			$this->response(10157, "账号被禁用");
		}
		\think\Db::startTrans();
		try {
			$data = $this->login_logic_handle($user);
			\think\Db::commit();
			$this->response(Code::success, "登录成功", $data);
		} catch (\Exception $e) {
			\think\Db::rollback();
			$this->response(Code::error, $e->getMessage());
		}
	}
	private function login_logic_handle($user)
	{
		$date = date("Y-m-d H:i:s");
		$user_safe_config = json_decode($this->project["user_safe_config"], true);
		$machine_code_binding_top_limit = !empty($user_safe_config["machine_code_binding_top_limit"]) ? $user_safe_config["machine_code_binding_top_limit"] : \app\common\model\DefaultConfig::UserMachineCodeBindingTopLimit;
		if ($user["machine_code_binding_top_limit"] != 0) {
			$machine_code_binding_top_limit = $user["machine_code_binding_top_limit"];
		}
		if (!empty($user_safe_config["machine_code_verify"]) && $user_safe_config["machine_code_verify"] == true) {
			if (!isset($this->input["machine_code"]) || $this->input["machine_code"] == "") {
				$this->response(10158, "当前缺少机器码参数machine_code");
			}
			if (!verifyMachineCode($this->input["machine_code"], $user["machine_code"], $machine_code_binding_top_limit)) {
				$this->response(10159, "机器码校验失败");
			}
		}
		if (empty($this->project["user_verify_mode"])) {
		} else {
			if ($this->project["user_verify_mode"] == 1) {
				if ($user["viptime"] < time() && !$user["is_forever_vip"]) {
					$this->response(10160, "会员时长已到期");
				}
			} elseif ($this->project["user_verify_mode"] == 2) {
			}
		}
		$user_machine_code = getUserMachineCodeList($user["machine_code"]);
		if (!empty($this->input["machine_code"]) && !in_array($this->input["machine_code"], $user_machine_code) && count($user_machine_code) < $machine_code_binding_top_limit) {
			$user_machine_code[] = $this->input["machine_code"];
			\think\Db::name("app_member_user")->where(["id" => $user["id"]])->update(["machine_code" => json_encode($user_machine_code, JSON_UNESCAPED_UNICODE)]);
		}
		$today = \think\helper\Time::today();
		if ($user["acttime"] < $today[0]) {
			\app\common\server\StatisticsData::increases($this->project["id"], \app\common\model\AppData::MemberAppUserActive, 1);
		}
		$online_machine_upper_limit = $user_safe_config["online_machine_upper_limit"] ?? \app\common\model\DefaultConfig::UserOnlineMachineUpperLimit;
		if ($user["online_machine_upper_limit"] != 0) {
			$online_machine_upper_limit = $user["online_machine_upper_limit"];
		}
		$minimum_active_time = time() - ($user_safe_config["online_time_difference"] ?? \app\common\model\DefaultConfig::AppUserHeartbeatInterval);
		$machine_code = $this->input["machine_code"] ?? "";
		$current_online_list = \think\Db::name("app_member_user_login_machine")->where([["appid", "=", $this->project["id"]], ["uid", "=", $user["id"]], ["active_time", ">", $minimum_active_time], ["machine_code", "<>", $machine_code], ["force_offline_status", "=", 0], ["token_status", "=", 0]])->order("login_time", "asc")->select();
		if ($online_machine_upper_limit <= count($current_online_list) && $online_machine_upper_limit > 0) {
			if (empty($user_safe_config["online_machine_upper_limit_login_scheme"])) {
				$this->response(10161, "当前无法登录,已在其他设备登录");
			} else {
				if ($user_safe_config["online_machine_upper_limit_login_scheme"] == 1) {
					\think\Db::name("app_member_user_login_machine")->where(["id" => $current_online_list[0]["id"]])->update(["token_status" => 1, "token" => ""]);
				}
			}
		}
		$login_machine = \think\Db::name("app_member_user_login_machine")->where(["appid" => $this->project["id"], "uid" => $user["id"], "machine_code" => $machine_code])->find();
		$binding_ip_list = json_decode($user["binding_ip_list"], true) ?? [];
		$machine_binding_ip_list = $login_machine ? json_decode($login_machine["binding_ip_list"], true) ?? [] : [];
		if (!empty($user_safe_config["ip_verify"])) {
			$ip_binding_top_limit = $user_safe_config["ip_binding_top_limit"] ?? \app\common\model\DefaultConfig::UserIpUpperLimit;
			if ($user["ip_binding_top_limit"] != 0) {
				$ip_binding_top_limit = $user["ip_binding_top_limit"];
			}
			$machine_ip_binding_top_limit = $user_safe_config["machine_ip_binding_top_limit"] ?? \app\common\model\DefaultConfig::UserMachineIpBindingTopLimit;
			if ($user["machine_ip_binding_top_limit"] != 0) {
				$machine_ip_binding_top_limit = $user["machine_ip_binding_top_limit"];
			}
			if ($ip_binding_top_limit > 0 && !in_array($this->client_ip, $binding_ip_list) && $ip_binding_top_limit <= count($binding_ip_list)) {
				$this->response(10162, "您的IP:" . $this->client_ip . "没有在绑定IP列表内无法进行登录");
			} else {
				if (!in_array($this->client_ip, $binding_ip_list)) {
					$binding_ip_list[] = $this->client_ip;
				}
			}
			if ($machine_ip_binding_top_limit > 0 && !in_array($this->client_ip, $machine_binding_ip_list) && $machine_ip_binding_top_limit <= count($machine_binding_ip_list)) {
				$this->response(10163, "您的IP:" . $this->client_ip . "没有在本设备绑定IP列表内无法进行登录");
			} else {
				if (!in_array($this->client_ip, $machine_binding_ip_list)) {
					$machine_binding_ip_list[] = $this->client_ip;
				}
			}
		}
		\think\Db::name("app_member_user")->where(["id" => $user["id"]])->update(["acttime" => time(), "force_offline_status" => 0, "binding_ip_list" => json_encode($binding_ip_list)]);
		$token = GenerateToken(["id" => $user["id"], "startTime" => time()]);
		if ($login_machine) {
			$token_info = json_decode(hex2bin($login_machine["token"]), true);
			if (!checkUserTokenInvalid($user_safe_config, $token_info) && empty($user_safe_config["token_update_mechanism"]) && $token_info) {
				$token = $login_machine["token"];
			}
			\think\Db::name("app_member_user_login_machine")->where(["id" => $login_machine["id"]])->update(["ip" => $this->client_ip, "token" => $token, "machine_info" => $this->input["machine_info"] ?? "", "login_time" => time(), "active_time" => time(), "token_status" => 0, "force_offline_status" => 0, "binding_ip_list" => json_encode($machine_binding_ip_list)]);
		} else {
			\think\Db::name("app_member_user_login_machine")->insert(["appid" => $this->project["id"], "uid" => $user["id"], "machine_code" => $machine_code, "machine_info" => $this->input["machine_info"] ?? "", "ip" => $this->client_ip, "token" => $token, "login_time" => time(), "active_time" => time(), "binding_ip_list" => json_encode($machine_binding_ip_list)]);
		}
		$user["token"] = $token;
		$data = ["user_id" => $user["id"], "user_token" => $user["token"], "data" => $this->get_user_info_array($user)];
		return $data;
	}
	private function get_user_info_array($user) : array
	{
		$user = \app\api\common\member\Growth::check_upgrade($user);
		$CurrentLevel = \think\Db::name("app_member_user_level")->where([["appid", "=", $user["appid"]], ["id", "=", $user["level_id"]]])->find();
		if (empty($CurrentLevel)) {
			$default_level = \think\Db::name("app_member_user_level")->where([["appid", "=", $user["appid"]], ["is_default", "=", 1]])->find();
			if (!empty($default_level)) {
				\think\Db::name("app_member_user")->where(["id" => $user["id"]])->update(["level_id" => $default_level["id"]]);
				$user["level_id"] = $default_level["id"];
				$CurrentLevel = $default_level;
			} else {
				$this->response(Code::error, "用户关联的等级不存在或未关联用户等级,系统自动关联失败,查询到用户等级库内无默认等级");
			}
		}
		$NextLevel = \think\Db::name("app_member_user_level")->where([["appid", "=", $user["appid"]], ["upgrade", "=", 1], ["level", ">", $CurrentLevel["level"]]])->find();
		$CappingGrowthValue = $NextLevel ? $NextLevel["integral"] : "full";
		$superiors = [];
		if ($user["superiors"]) {
			$superiors_data = \think\Db::name("app_member_user")->where(["id" => $user["superiors"]])->find();
			$superiors = ["uid" => $superiors_data["id"], "nickname" => $superiors_data["nickname"], "avatar" => $superiors_data["avatar"]];
		}
		$surplusTime = $user["viptime"] - time();
		$data = ["userInfo" => ["id" => $user["id"], "account" => $user["account"], "nickname" => $user["nickname"], "avatar" => $user["avatar"], "point" => $user["point"], "addtime" => $user["addtime"], "viptime" => $user["viptime"], "qqunionid" => $user["qqunionid"], "qqopenid" => $user["qqopenid"], "background" => $user["background"], "is_forever_vip" => $user["is_forever_vip"], "self_service_unbinding_time" => $user["self_service_unbinding_time"], "private_data" => (object) get_app_user_private_data($this->project, $user["private_data"], "user"), "superiors_user_info" => $superiors ?: (object) [], "growth" => $user["growth"], "capping_growth_value" => $CappingGrowthValue, "user_current_level_info" => ["id" => $CurrentLevel["id"], "level" => $CurrentLevel["level"], "name" => $CurrentLevel["name"]], "user_next_level_info" => $NextLevel ? ["id" => $NextLevel["id"], "level" => $NextLevel["level"], "name" => $NextLevel["name"]] : (object) [], "mail" => $user["mail"]], "surplusVipTime" => ["second" => $surplusTime, "minute" => intval($surplusTime % 86400 % 3600 / 60), "hour" => intval($surplusTime % 86400 / 3600), "day" => intval($surplusTime / 86400)], "vipExpireTimeStr" => $user["viptime"] > \time() || $user["is_forever_vip"] == 1 ? date("Y-m-d H:i:s", $user["viptime"]) : "非会员"];
		return $data;
	}
	public function register()
	{
		$validate = \think\Validate::make(["account" => "require", "password" => "require", "machine_code" => "require"], ["account.require" => "用户名 不能为空！", "password.require" => "密码 不能为空！", "machine_code.require" => "机器码 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		$isSystemAuthUnpaid = isSystemAuthUnpaid();
		if ($isSystemAuthUnpaid && \think\Db::name("app_member_user")->where(["appid" => $this->project["id"]])->count() >= \app\common\model\FreeQuota::MemberAppUserQuota) {
			return ["code" => Code::fail, "msg" => "当前授权为基础版,一个应用最多只能注册" . \app\common\model\FreeQuota::MemberAppUserQuota . "个用户" . \app\common\model\DefaultConfig::SystemAuthUnpaidSuffixText];
		}
		\think\Db::startTrans();
		try {
			$member_app_config = json_decode($this->project["member_app_config"], true);
			if (!empty($member_app_config["register_config"]["close"])) {
				$this->response(10164, "未开启注册");
			}
			$user = \think\Db::name("app_member_user")->where(["appid" => $this->project["id"], "account" => $this->input["account"]])->find();
			if (!empty($user)) {
				$this->response(10165, "用户名不可用请更换");
			}
			$ip = $this->client_ip;
			if (!empty($member_app_config["register_config"]["register_frequency_limit_type"]) && !empty($member_app_config["register_config"]["register_frequency_limit_value"])) {
				$register_time_between = \app\common\helper\Time::get_cycle_time($member_app_config["register_config"]["register_frequency_limit_type"]);
				if (\think\Db::name("app_member_user")->where([["register_ip", "=", $ip], ["addtime", "between", $register_time_between]])->count() >= $member_app_config["register_config"]["register_frequency_limit_value"]) {
					$this->response(10166, "当前IP注册用户已达上限");
				}
			}
			if (\think\Db::name("app_member_user_level")->where(["appid" => $this->project["id"], "is_default" => 1])->count() == 0) {
				$this->response(10167, "应用后台没有找到默认用户等级，请先在后台添加设置好用户默认等级");
			}
			$avatar = $this->input["avatar"] ?? "";
			if (is_numeric($avatar)) {
				$file = \think\Db::name("public_upload_log")->where(["id" => $avatar])->find();
				if ($file) {
					if (empty($file["channel"])) {
						$avatar = get_static_resources_url($file["uri"]);
					} else {
						$avatar = $file["url"];
					}
					\think\Db::name("public_upload_log")->where(["id" => $avatar])->update(["overtime" => 0]);
				}
			}
			$data = ["appid" => $this->project["id"], "account" => $this->input["account"], "machine_code" => $this->input["machine_code"], "password" => GeneratePassword($this->input["password"]), "nickname" => $this->input["nickname"] ?? "昵称未设置", "avatar" => $avatar, "register_ip" => $ip, "addtime" => time()];
			$user = $this->user_register_handle($data);
			\think\Db::commit();
			$this->response(Code::success, "注册成功", ["id" => $user["id"], "account" => $this->input["account"], "password" => $this->input["password"]]);
		} catch (\Exception $e) {
			\think\Db::rollback();
			$this->response(Code::error, "注册失败 " . $e->getMessage());
		}
	}
	public function revise_private_data()
	{
		$validate = \think\Validate::make(["field" => "require", "content" => "require"], ["field.require" => "字段名 不能为空！", "content.require" => "修改内容 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		list($verify_code, $user) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, new \app\api\common\entity\MemberAppUserVerify());
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $user);
		}
		\think\Db::startTrans();
		try {
			$user_private_data_config = json_decode($this->project["user_private_data_config"], true);
			$private_data = json_decode($user["private_data"], true);
			$field_exist = false;
			$current_field_config = [];
			if ($user_private_data_config) {
				foreach ($user_private_data_config as $private_data_item) {
					if ($private_data_item["field"] == $this->input["field"]) {
						$field_exist = true;
						$current_field_config = $private_data_item;
						break;
					}
				}
			}
			if ($field_exist) {
				if (empty($current_field_config["authority"]["revise"])) {
					$this->response(Code::fail, "没有修改权限");
				}
				$original_content = $private_data[$this->input["field"]] ?? "";
				$private_data[$this->input["field"]] = $this->input["content"];
				\think\Db::name("app_member_user")->where(["id" => $user["id"]])->update(["private_data" => json_encode($private_data, JSON_FORCE_OBJECT)]);
				\think\Db::commit();
				$this->response(Code::success, "修改成功", ["original_content" => $original_content, "new_content" => $this->input["content"]]);
			} else {
				$this->response(Code::fail, "字段不存在");
			}
		} catch (\Exception $e) {
			\think\Db::rollback();
			$this->response(Code::error, $e->getMessage());
		}
	}
	public function self_service_unbinding()
	{
		$validate = \think\Validate::make(["account" => "require"], ["account.require" => "账号 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		$user_safe_config = json_decode($this->project["user_safe_config"], true);
		list($verify_code, $user) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, new \app\api\common\entity\MemberAppUserVerify());
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $user);
		}
		if ($user["machine_code"] == "") {
			$this->response(Code::fail, "当前未绑定机器码无需解绑");
		}
		\think\Db::startTrans();
		try {
			if (!empty($user_safe_config["self_service_unbinding"]["open"])) {
				if (!empty($user_safe_config["self_service_unbinding"]["interval"]) && $user["self_service_unbinding_time"] > time()) {
					$this->response(Code::fail, "解绑时间未到");
				}
				$self_service_unbinding_time = time() + $user_safe_config["self_service_unbinding"]["interval"];
				if (!empty($user_safe_config["self_service_unbinding"]["frequency_limit_type"])) {
					list($time_start, $time_end) = \app\common\helper\Time::get_cycle_time($user_safe_config["self_service_unbinding"]["frequency_limit_type"]);
					$count = \think\Db::name("app_member_user_unbinding_log")->where([["user_id", "=", $user["id"]], ["time", ">=", $time_start], ["time", "<=", $time_end]])->count();
					if ($user_safe_config["self_service_unbinding"]["frequency_limit_value"] <= $count) {
						$this->response(Code::fail, "当前时间不可解绑");
					}
				}
				if (!empty($user_safe_config["self_service_unbinding"]["deduction_time"])) {
					if ($user["viptime"] - $user_safe_config["self_service_unbinding"]["deduction_time"] < time()) {
						$this->response(Code::fail, "无法解绑,您的剩余时长不足以解绑扣除");
					} else {
						$logid = \app\api\common\member\Finance::set($user, "viptime", $user["viptime"] - $user_safe_config["self_service_unbinding"]["deduction_time"], 0, "自助解绑扣除时长", \app\common\model\MemberAppModel::UserVipTimeLogSourceSelfUnbinding);
					}
				}
				$update = ["machine_code" => "", "self_service_unbinding_time" => $self_service_unbinding_time, "force_offline_status" => 1];
				if (!empty($user_safe_config["self_service_unbinding"]["clear_binding_ip_list"])) {
					$update["binding_ip_list"] = "";
				}
				\think\Db::name("app_member_user")->where(["id" => $user["id"]])->update($update);
				if (!empty($user_safe_config["self_service_unbinding"]["clear_machine_binding_ip_list"])) {
					\think\Db::name("app_member_user_login_machine")->where(["uid" => $user["id"]])->update(["binding_ip_list" => ""]);
				}
				\think\Db::name("app_member_user_unbinding_log")->insert(["appid" => $user["appid"], "user_id" => $user["id"], "time" => time(), "source" => \app\common\model\MemberAppModel::UserUnBindingLogSourceSelfUnbinding]);
				\think\Db::commit();
				$this->response(Code::success, "解绑成功", []);
			} else {
				$this->response(Code::fail, "未开启自助解绑功能");
			}
		} catch (\Exception $e) {
			\think\Db::rollback();
			$this->response(Code::error, $e->getMessage());
		}
	}
	public static function verify_user($project, $apiInfo, $apiConfig, $input, \app\api\common\entity\MemberAppUserVerify $verify) : array
	{
		try {
			$user_safe_config = json_decode($project["user_safe_config"], true);
			if (isset($user_safe_config["token_verify_open"]) && $user_safe_config["token_verify_open"]) {
				$verify->setToken(true);
			}
			if (isset($user_safe_config["machine_code_verify"]) && $user_safe_config["machine_code_verify"]) {
				$verify->setMachineCode(true);
			} else {
				$verify->setMachineCode(false);
			}
			if (isset($user_safe_config["ip_verify"]) && $user_safe_config["ip_verify"]) {
				$verify->setIp(true);
			}
			if ($apiConfig && !empty($apiConfig["verify_user_token"])) {
				if ($apiConfig["verify_user_token"] === 1) {
					$verify->setToken(true);
				} elseif ($apiConfig["verify_user_token"] === 2) {
					$verify->setToken(false);
				}
			}
			if ($apiConfig && !empty($apiConfig["verify_machine_code"])) {
				if ($apiConfig["verify_machine_code"] === 1) {
					$verify->setMachineCode(true);
				} elseif ($apiConfig["verify_machine_code"] === 2) {
					$verify->setMachineCode(false);
				}
			}
			if ($apiConfig && !empty($apiConfig["verify_ip"])) {
				if ($apiConfig["verify_ip"] === 1) {
					$verify->setIp(true);
				} elseif ($apiConfig["verify_ip"] === 2) {
					$verify->setIp(false);
				}
			}
			$verify->setToken(true);
			if ($apiInfo["id"] == 12) {
				if (empty($user_safe_config["self_service_unbinding"]["verify_user_token"])) {
					$verify->setToken(false);
				} else {
					$verify->setToken(true);
				}
				if (empty($user_safe_config["self_service_unbinding"]["verify_original_machine"])) {
					$verify->setMachineCode(false);
				} else {
					$verify->setMachineCode(true);
				}
				if (empty($user_safe_config["self_service_unbinding"]["verify_ip"])) {
					$verify->setIp(false);
				} else {
					$verify->setIp(true);
				}
			}
			if ($apiInfo["id"] == 35) {
				$verify->setToken(false);
			}
			if (isset($input["user_id"])) {
				$user = \think\Db::name("app_member_user")->where(["appid" => $input["appid"], "id" => $input["user_id"]])->find();
			} else {
				$user = \think\Db::name("app_member_user")->where(["appid" => $input["appid"], "account" => $input["account"] ?? ""])->find();
			}
			if (empty($user)) {
				return [10168, "用户不存在"];
			}
			if ($user["disable"] == 1) {
				return [10169, "用户被禁用"];
			}
			if ($apiInfo["verify_user"] !== 0) {
				if ($verify->isMachineCode()) {
					if (!isset($input["machine_code"]) || $input["machine_code"] == "") {
						return [10170, "当前缺少机器码参数machine_code"];
					}
					$machine_code_binding_top_limit = !empty($user_safe_config["machine_code_binding_top_limit"]) ? $user_safe_config["machine_code_binding_top_limit"] : \app\common\model\DefaultConfig::UserMachineCodeBindingTopLimit;
					if ($user["machine_code_binding_top_limit"] != 0) {
						$machine_code_binding_top_limit = $user["machine_code_binding_top_limit"];
					}
					if (!verifyMachineCode($input["machine_code"], $user["machine_code"], $machine_code_binding_top_limit)) {
						return [10171, "机器码校验失败"];
					}
				}
				$login_machine = \think\Db::name("app_member_user_login_machine")->where(["appid" => $project["id"], "uid" => $user["id"], "machine_code" => $input["machine_code"] ?? ""])->find();
				if ($verify->isToken()) {
					if (empty($login_machine) || empty($input["user_token"]) || $login_machine["token"] != $input["user_token"]) {
						return [10172, "用户token校验失败"];
					}
					if ($login_machine["token_status"] == 1) {
						return [10173, "已在其他设备登录"];
					}
					if ($login_machine["token_status"] == 2) {
						return [10174, "用户身份失效"];
					}
					if ($login_machine["token_status"] == 3) {
						return [10175, "登录状态失效"];
					}
					$token_info = json_decode(hex2bin($input["user_token"]), true);
					if ($user["force_offline_status"] == 1 || $login_machine["force_offline_status"] == 1) {
						return [10176, "您被强制下线"];
					}
					if (checkUserTokenInvalid($user_safe_config, $token_info)) {
						return [10177, "用户token失效"];
					}
				}
				if ($verify->isIp()) {
					$binding_ip_list = json_decode($user["binding_ip_list"], true) ?? [];
					$machine_binding_ip_list = $login_machine ? json_decode($login_machine["binding_ip_list"], true) ?? [] : [];
					$ip_binding_top_limit = $user_safe_config["ip_binding_top_limit"] ?? \app\common\model\DefaultConfig::UserIpUpperLimit;
					if ($user["ip_binding_top_limit"] != 0) {
						$ip_binding_top_limit = $user["ip_binding_top_limit"];
					}
					$machine_ip_binding_top_limit = $user_safe_config["machine_ip_binding_top_limit"] ?? \app\common\model\DefaultConfig::UserMachineIpBindingTopLimit;
					if ($user["machine_ip_binding_top_limit"] != 0) {
						$machine_ip_binding_top_limit = $user["machine_ip_binding_top_limit"];
					}
					if ($ip_binding_top_limit > 0 && !in_array(client_ip, $binding_ip_list)) {
						return [10178, "绑定ip验证失败,您的IP:" . client_ip . "没有在绑定IP列表内"];
					}
					if ($machine_ip_binding_top_limit > 0 && !in_array(client_ip, $machine_binding_ip_list)) {
						return [10179, "绑定ip验证失败,您的IP:" . client_ip . "没有在本设备绑定IP列表内"];
					}
				}
			}
			return [Code::success, $user, $login_machine ?? []];
		} catch (\Exception $e) {
			return [Code::error, "系统错误:" . $e->getMessage()];
		}
	}
	public function get_user_info()
	{
		$validate = \think\Validate::make(["user_id" => "require"], ["user_id.require" => "用户ID 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		$user = \think\Db::name("app_member_user")->where(["appid" => $this->project["id"], "id" => $this->input["user_id"]])->find();
		if (empty($user)) {
			$this->response(10180, "用户不存在");
		}
		$data = $this->get_user_info_array($user);
		if (isset($this->input["update_active"])) {
			$verify = new \app\api\common\entity\MemberAppUserVerify();
			list($verify_code, $user) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, $verify);
			if ($verify_code !== Code::success) {
				$this->response($verify_code, $user);
			}
			\think\Db::name("app_member_user")->where(["id" => $user["id"]])->update(["acttime" => time()]);
			$machine_code = $this->input["machine_code"] ?? "";
			$login_machine = \think\Db::name("app_member_user_login_machine")->where(["appid" => $this->project["id"], "uid" => $user["id"], "machine_code" => $machine_code])->find();
			if ($login_machine) {
				\think\Db::name("app_member_user_login_machine")->where(["id" => $login_machine["id"]])->update(["active_time" => time()]);
			}
		} else {
			unset($data["userInfo"]["private_data"]);
			unset($data["userInfo"]["self_service_unbinding_time"]);
			unset($data["userInfo"]["superiors_user_info"]);
			unset($data["userInfo"]["self_service_unbinding_time"]);
		}
		$this->response(Code::success, "获取成功", $data);
	}
	public function use_card()
	{
		$validate = \think\Validate::make(["account" => "require", "card" => "require"], ["account.require" => "账户 不能为空！", "card.require" => "卡密 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		list($verify_code, $user) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, new \app\api\common\entity\MemberAppUserVerify());
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $user);
		}
		$card = findCardCaseSensitive("app_member_card", ["appid" => $this->project["id"], "card" => $this->input["card"]]);
		if (empty($card)) {
			$this->response(10181, "卡密不存在");
		}
		if ($card["status"] == 1) {
			$this->response(10182, "卡密已使用");
		}
		try {
			\think\Db::startTrans();
			if ($card["agent_id"]) {
				$appBinding = \think\Db::name("app_agent_binding")->where(["agent_id" => $card["agent_id"]])->find();
				if ($appBinding && $appBinding["card_disable"]) {
					$this->response(10183, "此卡由于上级相关权限被关闭,已作废不可使用");
				}
			}
			if ($card["type"] == 0) {
				if ($user["is_forever_vip"] == 1) {
					$this->response(10184, "您的会员时长已是永久到期无法继续续费时长");
				}
				$time_type = $card["time_type"];
				$time_value = empty($card["value"]) ? 1 : $card["value"];
				$viptime = \app\common\helper\Time::computing_time($time_type, $time_value, $user["viptime"]);
				\app\api\common\member\Finance::set($user, "viptime", $viptime, 0, "使用充值卡{$card["card"]}充值", \app\common\model\MemberAppModel::UserVipTimeLogSourceRechargeableCard);
			} elseif ($card["type"] == 1) {
				\app\api\common\member\Finance::set($user, "point", $card["value"], 0, "使用充值卡{$card["card"]}充值", \app\common\model\MemberAppModel::UserPointLogSourceRechargeableCard);
			}
			\think\Db::name("app_member_card")->where(["id" => $card["id"]])->update(["usetime" => time(), "status" => 1, "useuid" => $user["id"]]);
			\think\Db::commit();
			$this->response(Code::success, "使用成功");
		} catch (\Exception $e) {
			\think\Db::rollback();
			$this->response(Code::error, "系统错误:" . $e->getMessage());
		}
	}
	public function increase_or_decrease_points()
	{
		$validate = \think\Validate::make(["type" => "require|in:0,1", "value" => "require|number", "remarks" => "require"], ["type.require" => "操作类型 不能为空！", "value.require" => "操作数量 不能为空！", "remarks.require" => "备注 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		list($verify_code, $user) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, new \app\api\common\entity\MemberAppUserVerify());
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $user);
		}
		$member_app_config = json_decode($this->project["member_app_config"], true);
		if (empty($member_app_config["point_config"]["api_increase_open"]) && $this->input["type"] == 0) {
			$this->response(10185, "未开启增加功能");
		}
		if (empty($member_app_config["point_config"]["api_reduce_open"]) && $this->input["type"] == 1) {
			$this->response(10186, "未开启减少功能");
		}
		if (!empty($member_app_config["point_config"]["api_increase_maximum"]) && $this->input["value"] > $member_app_config["point_config"]["api_increase_maximum"] && $this->input["type"] == 0) {
			$this->response(10187, "增加数量不能超过" . $member_app_config["point_config"]["api_increase_maximum"]);
		}
		if (!empty($member_app_config["point_config"]["api_increase_minimum"]) && $this->input["value"] < $member_app_config["point_config"]["api_increase_minimum"] && $this->input["type"] == 0) {
			$this->response(10188, "增加数量不能小于" . $member_app_config["point_config"]["api_increase_minimum"]);
		}
		if (!empty($member_app_config["point_config"]["api_reduce_maximum"]) && $this->input["value"] > $member_app_config["point_config"]["api_reduce_maximum"] && $this->input["type"] == 1) {
			$this->response(10189, "减少数量不能超过" . $member_app_config["point_config"]["api_reduce_maximum"]);
		}
		if (!empty($member_app_config["point_config"]["api_reduce_minimum"]) && $this->input["value"] < $member_app_config["point_config"]["api_reduce_minimum"] && $this->input["type"] == 1) {
			$this->response(10190, "减少数量不能小于" . $member_app_config["point_config"]["api_reduce_minimum"]);
		}
		if (!empty($member_app_config["point_config"]["api_increase_frequency_limit_type"]) && $this->input["type"] == 0) {
			list($time_start, $time_end) = \app\common\helper\Time::get_cycle_time($member_app_config["point_config"]["api_increase_frequency_limit_type"]);
			$count = \think\Db::name("app_member_user_finance_log")->where([["user_id", "=", $user["id"]], ["time", ">=", $time_start], ["time", "<=", $time_end], ["field", "=", "point"], ["source", "=", \app\common\model\MemberAppModel::UserPointLogSourceClientApi]])->count();
			if ($member_app_config["point_config"]["api_increase_frequency_limit_value"] <= $count) {
				$this->response(10191, "周期次数已上限");
			}
		}
		if (!empty($member_app_config["point_config"]["api_increase_quantity_limit_type"]) && $this->input["type"] == 0) {
			list($time_start, $time_end) = \app\common\helper\Time::get_cycle_time($member_app_config["point_config"]["api_increase_quantity_limit_type"]);
			$sum = \think\Db::name("app_member_user_finance_log")->where([["user_id", "=", $user["id"]], ["time", ">=", $time_start], ["time", "<=", $time_end], ["field", "=", "point"], ["source", "=", \app\common\model\MemberAppModel::UserPointLogSourceClientApi]])->sum("number");
			if ($sum + $this->project["value"] > $member_app_config["point_config"]["api_increase_quantity_limit_value"]) {
				$this->response(10192, "周期数量已上限");
			}
		}
		if ($this->input["type"] == 1 && $user["point"] < $this->input["value"]) {
			$this->response(10193, "当前数量不足以减少扣除");
		}
		\think\Db::startTrans();
		try {
			$logid = \app\api\common\member\Finance::set($user, "point", $this->input["value"], $this->input["type"], "客户端API操作,备注:" . $this->input["remarks"], \app\common\model\MemberAppModel::UserPointLogSourceClientApi);
			\think\Db::commit();
			$this->response(Code::success, "操作成功", ["original_point" => $user["point"], "new_point" => \think\Db::name("app_member_user")->where(["id" => $user["id"]])->value("point", 0)]);
		} catch (\Exception $e) {
			\think\Db::rollback();
			$this->response(Code::error, $e->getMessage());
		}
	}
	public function increase_or_decrease_time()
	{
		$validate = \think\Validate::make(["auth" => "require", "type" => "require|in:0,1", "value" => "require|number", "remarks" => "require"], ["auth.require" => "授权 不能为空！", "type.require" => "操作类型 不能为空！", "value.require" => "操作数量 不能为空！", "remarks.require" => "备注 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		list($verify_code, $user) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, new \app\api\common\entity\MemberAppUserVerify());
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $user);
		}
		$member_app_config = json_decode($this->project["member_app_config"], true);
		if (empty($member_app_config["time_config"]["api_increase_open"]) && $this->input["type"] == 0) {
			$this->response(10291, "未开启增加功能");
		}
		if (empty($member_app_config["time_config"]["api_reduce_open"]) && $this->input["type"] == 1) {
			$this->response(10292, "未开启减少功能");
		}
		if (!empty($member_app_config["time_config"]["api_increase_maximum"]) && $this->input["value"] > $member_app_config["time_config"]["api_increase_maximum"] && $this->input["type"] == 0) {
			$this->response(10293, "增加数量不能超过" . $member_app_config["time_config"]["api_increase_maximum"]);
		}
		if (!empty($member_app_config["time_config"]["api_increase_minimum"]) && $this->input["value"] < $member_app_config["time_config"]["api_increase_minimum"] && $this->input["type"] == 0) {
			$this->response(10294, "增加数量不能小于" . $member_app_config["time_config"]["api_increase_minimum"]);
		}
		if (!empty($member_app_config["time_config"]["api_reduce_maximum"]) && $this->input["value"] > $member_app_config["time_config"]["api_reduce_maximum"] && $this->input["type"] == 1) {
			$this->response(10295, "减少数量不能超过" . $member_app_config["time_config"]["api_reduce_maximum"]);
		}
		if (!empty($member_app_config["time_config"]["api_reduce_minimum"]) && $this->input["value"] < $member_app_config["time_config"]["api_reduce_minimum"] && $this->input["type"] == 1) {
			$this->response(10296, "减少数量不能小于" . $member_app_config["time_config"]["api_reduce_minimum"]);
		}
		if (!empty($member_app_config["time_config"]["api_increase_frequency_limit_type"]) && $this->input["type"] == 0) {
			list($time_start, $time_end) = \app\common\helper\Time::get_cycle_time($member_app_config["time_config"]["api_increase_frequency_limit_type"]);
			$count = \think\Db::name("app_member_user_finance_log")->where([["user_id", "=", $user["id"]], ["time", ">=", $time_start], ["time", "<=", $time_end], ["field", "=", "point"], ["source", "=", \app\common\model\MemberAppModel::UserVipTimeLogSourceClientApi]])->count();
			if ($member_app_config["time_config"]["api_increase_frequency_limit_value"] <= $count) {
				$this->response(10297, "周期次数已上限");
			}
		}
		if (!empty($member_app_config["time_config"]["api_increase_quantity_limit_type"]) && $this->input["type"] == 0) {
			list($time_start, $time_end) = \app\common\helper\Time::get_cycle_time($member_app_config["time_config"]["api_increase_quantity_limit_type"]);
			$sum = \think\Db::name("app_member_user_finance_log")->where([["user_id", "=", $user["id"]], ["time", ">=", $time_start], ["time", "<=", $time_end], ["field", "=", "point"], ["source", "=", \app\common\model\MemberAppModel::UserVipTimeLogSourceClientApi]])->sum("number");
			if ($sum + $this->project["value"] > $member_app_config["time_config"]["api_increase_quantity_limit_value"]) {
				$this->response(10298, "周期数量已上限");
			}
		}
		if ($this->input["type"] == 1 && $user["viptime"] < time()) {
			$this->response(10299, "当前是非会员状态");
		}
		\think\Db::startTrans();
		try {
			$logid = \app\api\common\member\Finance::set($user, "viptime", $this->input["value"], $this->input["type"], "客户端API操作,备注:" . $this->input["remarks"], \app\common\model\MemberAppModel::UserVipTimeLogSourceClientApi);
			\think\Db::commit();
			$this->response(Code::success, "操作成功");
		} catch (\Exception $e) {
			\think\Db::rollback();
			$this->response(Code::error, $e->getMessage());
		}
	}
	public function get_signing_data()
	{
		list($verify_code, $user) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, new \app\api\common\entity\MemberAppUserVerify());
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $user);
		}
		$member_app_config = json_decode($this->project["member_app_config"], true);
		$config = $member_app_config["signing_config"] ?? [];
		list($timeStart, $timeEnd) = \think\helper\Time::month();
		if (isset($config["cycle"])) {
			foreach ($config["continuity"] as $count => $body) {
				$config["continuity"][$count]["is_receive_reward"] = false;
				if (\think\Db::name("app_member_user_signing_reward_log")->where([["uid", "=", $user["id"]], ["type", "=", 1], ["count", "=", $count], ["time", ">=", $timeStart], ["time", "<", $timeEnd]])->count()) {
					$config["continuity"][$count]["is_receive_reward"] = true;
				}
			}
			foreach ($config["total"] as $count => $body) {
				$config["total"][$count]["is_receive_reward"] = false;
				if (\think\Db::name("app_member_user_signing_reward_log")->where(["uid" => $user["id"], "type" => 0, "count" => $count])->count()) {
					$config["total"][$count]["is_receive_reward"] = true;
				}
			}
			$days = \app\common\helper\Time::get_month_dates();
			$last_signin_log = \think\Db::name("app_member_user_signing_log")->where("uid", $user["id"])->order("id", "desc")->find();
			$user_data = ["cycle_signing_log" => [], "total" => \think\Db::name("app_member_user_signing_log")->where("uid", $user["id"])->count(), "continuity_cycle" => !$last_signin_log ? 0 : $last_signin_log["continuity_cycle"], "continuitys" => !$last_signin_log ? 0 : $last_signin_log["continuitys"], "last_signing_log" => !$last_signin_log ? [] : $last_signin_log];
			foreach ($days as $day) {
				$day_data = ["is_signing" => \think\Db::name("user_signing_log")->where([["uid", "=", $user["id"]], ["date", "=", $day]])->count()];
				$user_data["cycle_signing_log"][$day] = $day_data;
			}
			$this->response(Code::success, "获取成功", ["user_data" => $user_data, "config" => $config]);
		} else {
			$this->response(10194, "后台未配置签到功能");
		}
	}
	public function submit_signing()
	{
		list($verify_code, $user) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, new \app\api\common\entity\MemberAppUserVerify());
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $user);
		}
		$date_format = "Y-m-d";
		$current_date = date($date_format);
		$last_signin_log = \think\Db::name("app_member_user_signing_log")->where("uid", $user["id"])->order("id", "desc")->find();
		if ($last_signin_log && $last_signin_log["date"] == date($date_format)) {
			$this->response(10195, "今日已签到");
		}
		$member_app_config = json_decode($this->project["member_app_config"], true);
		$config = $member_app_config["signing_config"] ?? [];
		$continuity_cycle = 1;
		$continuitys = 1;
		if (isset($config["cycle"])) {
			\think\Db::startTrans();
			try {
				if ($last_signin_log && $last_signin_log["date"] == date($date_format, strtotime($current_date . " -1 day"))) {
					$continuitys++;
				}
				if ($config["cycle"] == 1 && date("d") != 1 && $last_signin_log["date"] == date($date_format, strtotime($current_date . " -1 day"))) {
					$continuity_cycle++;
				}
				\think\Db::name("app_member_user_signing_log")->insert(["appid" => $user["appid"], "uid" => $user["id"], "time" => time(), "date" => $current_date, "continuity_cycle" => $continuity_cycle, "continuitys" => $continuitys]);
				$gift_info = ["viptime" => 0, "point" => 0, "growth" => 0];
				if ($last_signin_log) {
					\app\api\common\member\Helper::SigningReward($user, "ordinary", "daily", $config["ordinary"]["daily"]["gift_data"], $gift_info);
				} else {
					\app\api\common\member\Helper::SigningReward($user, "ordinary", "first", $config["ordinary"]["first"]["gift_data"], $gift_info);
				}
				if (isset($config["special"][date("Y-m-d")])) {
					\app\api\common\member\Helper::SigningReward($user, "special", date("Y-m-d"), $config["special"][date("Y-m-d")]["gift_data"], $gift_info);
				}
				\think\Db::commit();
				$this->response(Code::success, "签到成功", ["gift_info" => $gift_info, "continuity_cycle" => $continuity_cycle, "continuitys" => $continuitys]);
			} catch (\Exception $e) {
				$this->response(Code::error, "签到失败" . $e->getMessage());
			}
		} else {
			$this->response(10196, "后台未配置签到功能");
		}
	}
	public function receive_signing_reward()
	{
		$validate = \think\Validate::make(["rule_type" => "require", "rule_value" => "require"], ["rule_type.require" => "规则类型 不能为空！", "rule_value.require" => "规则 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		list($verify_code, $user) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, new \app\api\common\entity\MemberAppUserVerify());
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $user);
		}
		$member_app_config = json_decode($this->project["member_app_config"], true);
		$config = $member_app_config["signing_config"] ?? [];
		$gift_info = ["viptime" => 0, "point" => 0, "growth" => 0];
		\think\Db::startTrans();
		$rule_value = $this->input["rule_value"];
		$rule_type = $this->input["rule_type"];
		try {
			if ($rule_type == "total") {
				if (\think\Db::name("app_member_user_signing_reward_log")->where(["uid" => $user["id"], "type" => $rule_type, "count" => $rule_value])->count()) {
					$this->response(10197, "奖励只能领取一次");
				}
				if (\think\Db::name("app_member_user_signing_log")->where("uid", $user["id"])->count() < $rule_value) {
					$this->response(10198, "签到次数未满足条件");
				}
				if (isset($config["total"][$rule_value])) {
					\app\api\common\member\Helper::SigningReward($user, "total", $rule_value, $config["total"][$rule_value]["gift_data"], $gift_info);
					\think\Db::name("app_member_user_signing_reward_log")->insert(["appid" => $user["appid"], "uid" => $user["id"], "type" => $rule_type, "count" => $rule_value, "time" => time()]);
				} else {
					$this->response(10199, "该奖励规则值不存在");
				}
			} elseif ($rule_type == "continuity") {
				list($timeStart, $timeEnd) = \think\helper\Time::month();
				if (\think\Db::name("app_member_user_signing_reward_log")->where([["uid", "=", $user["id"]], ["type", "=", $rule_type], ["count", "=", $rule_value], ["time", ">=", $timeStart], ["time", "<", $timeEnd]])->count()) {
					$this->response(10197, "奖励只能领取一次");
				}
				$last_signin_log = \think\Db::name("app_member_user_signing_log")->where("uid", $user["id"])->order("id", "desc")->find();
				if ($last_signin_log && $last_signin_log["continuity_cycle"] < $rule_value) {
					$this->response(10198, "签到次数未满足条件");
				}
				if (isset($config["continuity"][$rule_value])) {
					\app\api\common\member\Helper::SigningReward($user, "continuity", $rule_value, $config["continuity"][$rule_value]["gift_data"], $gift_info);
					\think\Db::name("app_member_user_signing_reward_log")->insert(["appid" => $user["appid"], "uid" => $user["id"], "type" => $rule_type, "count" => $rule_value, "time" => time()]);
				} else {
					$this->response(10199, "该奖励规则值不存在");
				}
			} else {
				$this->response(10290, "该奖励规则类型不存在");
			}
			\think\Db::commit();
			$this->response(Code::success, "领取成功", $gift_info);
		} catch (\Exception $e) {
			\think\Db::rollback();
			$this->response(Code::error, "领取失败" . $e->getMessage());
		}
	}
	public function get_user_level_list()
	{
		$list = \think\Db::name("app_member_user_level")->where(["appid" => $this->project["id"]])->select();
		$data = [];
		foreach ($list as $item) {
			$data = $item;
		}
		$this->response(Code::success, "获取成功", ["list" => $data]);
	}
	public function get_user_register_config()
	{
		$member_app_config = json_decode($this->project["member_app_config"], true);
		$this->response(Code::success, "获取成功", $member_app_config["register_config"] ?? []);
	}
	public function get_user_signing_config()
	{
		$member_app_config = json_decode($this->project["member_app_config"], true);
		$this->response(Code::success, "获取成功", $member_app_config["signing_config"] ?? []);
	}
	public function qq_login()
	{
		$validate = \think\Validate::make(["access_token" => "require", "machine_code" => "require"], ["access_token.require" => "access_token 不能为空！", "machine_code.require" => "机器码 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		$member_app_config = json_decode($this->project["member_app_config"], true);
		if (empty($member_app_config["qq_connect_config"]["mobile"]["appid"])) {
			$this->response(10200, "未配置移动QQ互联");
		}
		$isSystemAuthUnpaid = isSystemAuthUnpaid();
		if ($isSystemAuthUnpaid && \think\Db::name("app_member_user")->where(["appid" => $this->project["id"]])->count() >= \app\common\model\FreeQuota::MemberAppUserQuota) {
			return ["code" => Code::fail, "msg" => "当前授权为基础版,一个应用最多只能注册" . \app\common\model\FreeQuota::MemberAppUserQuota . "个用户" . \app\common\model\DefaultConfig::SystemAuthUnpaidSuffixText];
		}
		$config = $member_app_config["qq_connect_config"];
		\think\Db::startTrans();
		try {
			$oauth = get_curl("https://graph.qq.com/oauth2.0/me?access_token={$this->input["access_token"]}&fmt=json&unionid=1");
			if (!$oauth) {
				$this->response(10201, "获取用户标识信息失败");
			}
			$oauth = json_decode($oauth, true);
			if (!isset($oauth["unionid"]) || $oauth["unionid"] == "") {
				$this->response(10202, "未得到unionid,请在QQ互联平台开启对应获取功能");
			}
			$info = get_curl("https://graph.qq.com/user/get_user_info?access_token={$this->input["access_token"]}&oauth_consumer_key={$config["mobile"]["appid"]}&openid={$oauth["openid"]}");
			if (!$info) {
				$this->response(10203, "获取QQ登录信息失败");
			}
			$account = $oauth["unionid"];
			$info = json_decode($info, true);
			$user = \think\Db::name("app_member_user")->where(["appid" => $this->project["id"], "qqunionid" => $oauth["unionid"]])->find();
			if (empty($user)) {
				if (!empty($member_app_config["register_config"]["qq_connect_close"])) {
					$this->response(10204, "未开放新用户注册");
				}
				$data = ["appid" => $this->project["id"], "account" => $account, "qqunionid" => $account, "qqopenid" => $oauth["openid"], "machine_code" => $this->input["machine_code"], "password" => GeneratePassword("123456"), "nickname" => $info["nickname"] ?? "昵称未设置", "avatar" => $info["figureurl_2"] ?? "", "register_ip" => $this->client_ip, "addtime" => time()];
				$user = $this->user_register_handle($data);
			}
			if ($user["qqopenid"] != $oauth["openid"]) {
				\think\Db::name("app_member_user")->where(["id" => $user["id"]])->update(["qqopenid" => $oauth["openid"]]);
			}
			$data = $this->login_logic_handle($user);
			\think\Db::commit();
			$this->response(Code::success, "登录成功", $data);
		} catch (\Exception $e) {
			\think\Db::rollback();
			$this->response(Code::error, "失败：" . $e->getMessage());
		}
	}
	public function qq_change_binding()
	{
		$validate = \think\Validate::make(["access_token" => "require"], ["access_token.require" => "access_token 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		list($verify_code, $user) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, new \app\api\common\entity\MemberAppUserVerify());
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $user);
		}
		try {
			\think\Db::startTrans();
			$oauth = get_curl("https://graph.qq.com/oauth2.0/me?access_token={$this->input["access_token"]}&fmt=json&unionid=1");
			if (!$oauth) {
				$this->response(10205, "获取用户标识信息失败");
			}
			$oauth = json_decode($oauth, true);
			if (!isset($oauth["unionid"]) || $oauth["unionid"] == "") {
				$this->response(10206, "未得到unionid,请在QQ互联平台开启对应获取功能");
			}
			$row = \think\Db::name("app_member_user")->where(["qqunionid" => $oauth["unionid"], "appid" => $user["appid"]])->find();
			if (!empty($row) && $row["id"] != $user["id"]) {
				$this->response(10207, "该QQ已被其他用户绑定");
			}
			\think\Db::name("app_member_user")->where(["id" => $user["id"]])->update(["qqunionid" => $oauth["unionid"], "qqopenid" => $oauth["openid"]]);
			\think\Db::commit();
			$this->response(Code::success, "绑定成功");
		} catch (\Exception $e) {
			\think\Db::rollback();
			$this->response(Code::error, "失败：" . $e->getMessage());
		}
	}
	public function qq_unbinding()
	{
		list($verify_code, $user) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, new \app\api\common\entity\MemberAppUserVerify());
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $user);
		}
		\think\Db::name("app_member_user")->where(["id" => $user["id"]])->update(["qqunionid" => "", "qqopenid" => ""]);
		$this->response(Code::success, "解绑成功");
	}
	public function revise_account_info()
	{
		list($verify_code, $user) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, new \app\api\common\entity\MemberAppUserVerify());
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $user);
		}
		try {
			\think\Db::startTrans();
			$avatar = $this->input["avatar"] ?? $user["avatar"];
			if (is_numeric($avatar)) {
				$file = \think\Db::name("public_upload_log")->where(["id" => $avatar])->find();
				if ($file) {
					if (empty($file["channel"])) {
						$avatar = get_static_resources_url($file["uri"]);
					} else {
						$avatar = $file["url"];
					}
					\think\Db::name("public_upload_log")->where(["id" => $avatar])->update(["overtime" => 0]);
				}
			}
			$data = ["nickname" => $this->input["nickname"] ?? $user["nickname"], "avatar" => $avatar];
			\think\Db::name("app_member_user")->where(["id" => $user["id"]])->update($data);
			\think\Db::commit();
			$this->response(Code::success, "修改成功");
		} catch (\Exception $e) {
			\think\Db::rollback();
			$this->response(Code::error, "失败：" . $e->getMessage());
		}
	}
	public function revise_account_password()
	{
		$validate = \think\Validate::make(["new_password" => "require"], ["original_password.require" => "原密码 不能为空！", "new_password.require" => "新密码 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		list($verify_code, $user) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, new \app\api\common\entity\MemberAppUserVerify());
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $user);
		}
		try {
			\think\Db::startTrans();
			memberUserPasswordChange($user, $this->input["new_password"]);
			\think\Db::commit();
			$this->response(Code::success, "修改成功");
		} catch (\Exception $e) {
			\think\Db::rollback();
			$this->response(Code::error, "失败：" . $e->getMessage());
		}
	}
	public function reset_account_password()
	{
		$validate = \think\Validate::make(["account" => "require", "original_password" => "require", "new_password" => "require"], ["account.require" => "账号 不能为空！", "original_password.require" => "原密码 不能为空！", "new_password.require" => "新密码 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		list($verify_code, $user) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, new \app\api\common\entity\MemberAppUserVerify());
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $user);
		}
		if ($user["password"] != GeneratePassword($this->input["original_password"])) {
			$this->response(10208, "原密码错误");
		}
		\think\Db::startTrans();
		try {
			memberUserPasswordChange($user, $this->input["new_password"]);
			\think\Db::commit();
			$this->response(Code::success, "重置成功");
		} catch (\Exception $e) {
			\think\Db::rollback();
			$this->response(Code::error, $e->getMessage());
		}
	}
	public function get_dynamic_list()
	{
		$page = $this->page_no;
		$limit = $this->page_size;
		$where[] = ["appid", "=", $this->project["id"]];
		if (!empty($this->input["uid"])) {
			$where[] = ["uid", "=", $this->input["uid"]];
		}
		if (!empty($this->input["is_relation"])) {
			list($verify_code, $user) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, new \app\api\common\entity\MemberAppUserVerify());
			if ($verify_code !== Code::success) {
				$this->response($verify_code, $user);
			}
			$where[] = ["uid", "in", \think\Db::name("app_member_user_relation")->where(["uid" => $user["id"]])->column("uuid")];
		}
		if (!empty($this->input["classify_id"])) {
			$where[] = ["cid", "=", $this->input["classify_id"]];
		}
		if (!empty($this->input["carry_video"])) {
			$where[] = ["carry_video", "=", 1];
		}
		if (!empty($this->input["carry_image"])) {
			$where[] = ["carry_image", "=", 1];
		}
		if (!empty($this->input["label_name"])) {
			$label = \think\Db::name("app_member_dynamic_label")->where(["appid" => $this->project["id"], "name" => $this->input["label_name"]])->find();
			if (empty($label)) {
				$where[] = ["id", "=", 0];
			} else {
				$where[] = ["", "exp", \think\Db::raw("FIND_IN_SET({$label["id"]},label_ids)")];
			}
		}
		if (!empty($this->input["label_id"])) {
			$where[] = ["", "exp", \think\Db::raw("FIND_IN_SET({$this->input["label_id"]},label_ids)")];
		}
		if (!empty($user)) {
			$where[] = ["", "exp", \think\Db::raw("status=1 or uid=" . $user["id"])];
		} else {
			$where[] = ["status", "=", 1];
		}
		$count = \think\Db::name("app_member_dynamic")->where($where)->count();
		$pages = ceil($count / $limit);
		$list = \think\Db::name("app_member_dynamic")->where($where)->page($page, $limit)->order("id", "desc")->select();
		$data = [];
		foreach ($list as $item) {
			$data[] = $this->get_dynamic_array($item, true);
		}
		$this->response(Code::success, "获取成功", ["list" => $data, "pages" => $pages, "count" => $count, "page" => $page]);
	}
	private function get_dynamic_array($item) : array
	{
		$user = \think\Db::name("app_member_user")->where(["id" => $item["uid"]])->find();
		list($verify_code, $self) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, new \app\api\common\entity\MemberAppUserVerify());
		$isLike = false;
		$isCollect = false;
		if ($verify_code == Code::success) {
			$like_log = \think\Db::name("app_member_dynamic_like_log")->where(["uid" => $self["id"], "dynamic_id" => $item["id"]])->find();
			if (!empty($like_log)) {
				$isLike = true;
			}
			$collect_log = \think\Db::name("app_member_dynamic_collect_log")->where(["uid" => $self["id"], "dynamic_id" => $item["id"]])->find();
			if (!empty($collect_log)) {
				$isCollect = true;
			}
		}
		$media_file_list = [];
		$media_file_ids = json_decode($item["media_file_ids"]) ?: [];
		foreach ($media_file_ids as $media_file_id) {
			$file = \think\Db::name("public_file_log")->where(["id" => $media_file_id])->find();
			if (!empty($file)) {
				if (empty($file["channel"])) {
					if ($file["type"] == 0) {
						$file["url"] = get_static_resources_url($file["uri"]);
					} elseif ($file["type"] == 1) {
						$file["url"] = get_static_resources_url($file["uri"], 1);
					} elseif ($file["type"] == 2) {
						$file["url"] = get_static_resources_url($file["uri"], 2);
					}
				}
				$media_file_list[] = $file;
			}
		}
		$label_ids = \think\Db::name("app_member_dynamic_label_ids")->where(["dynamic_id" => $item["id"]])->column("label_id");
		$label_list = \think\Db::name("app_member_dynamic_label")->whereIn("id", $label_ids)->field("id,name")->select();
		$data = ["id" => $item["id"], "uid" => $item["uid"], "title" => $item["title"], "content" => $item["content"], "addtime" => $item["addtime"], "status" => $item["status"], "media_file_list" => $media_file_list, "user_info" => ["id" => $user["id"], "avatar" => $user["avatar"], "nickname" => $user["nickname"]], "isLike" => $isLike, "isCollect" => $isCollect, "likeNumber" => \think\Db::name("app_member_dynamic_like_log")->where(["dynamic_id" => $item["id"]])->count(), "collectNumber" => \think\Db::name("app_member_dynamic_collect_log")->where(["dynamic_id" => $item["id"]])->count(), "browseUserNumber" => \think\Db::name("app_member_dynamic_browse_log")->where(["dynamic_id" => $item["id"]])->count(), "browseNumber" => $item["browse"], "chatNumber" => \think\Db::name("app_member_dynamic_comment")->where(["dynamic_id" => $item["id"]])->count(), "classify_info" => \think\Db::name("app_member_dynamic_classify")->where(["id" => $item["cid"]])->find(), "label_list" => $label_list ?: [], "carry_image" => $item["carry_image"], "carry_video" => $item["carry_video"]];
		$is_already_get_hidden_content = $this->dynamic_check_is_already_get_hidden_content($verify_code, $self, $item);
		$data["is_exist_hidden_content"] = \boolval($item["hidden_content"]);
		$data["is_already_get_hidden_content"] = $is_already_get_hidden_content;
		if ($is_already_get_hidden_content) {
			$data["hidden_content"] = $item["hidden_content"];
		} else {
			$data["hidden_content"] = "";
		}
		$share_file_list = json_decode($item["share_file_list"]) ?: [];
		foreach ($share_file_list as $share_file_index => $share_file_item) {
			$is_already_get_share_file = $this->dynamic_check_is_already_get_share_file($verify_code, $self, $share_file_item["file_id"]);
			$share_file_list[$share_file_index]["is_already_get_share_file"] = $is_already_get_share_file;
		}
		$data["share_file_list"] = $share_file_list;
		return $data;
	}
	public function get_dynamic_info()
	{
		$validate = \think\Validate::make(["id" => "require"], ["id.require" => "id 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		$id = $this->input["id"];
		$dynamic_config = json_decode($this->project["member_app_config"], true)["dynamic_config"] ?? [];
		$item = \think\Db::name("app_member_dynamic")->where(["id" => $id, "appid" => $this->project["id"]])->find();
		if (empty($item)) {
			$this->response(10209, "动态ID不存在");
		}
		\think\Db::name("app_member_dynamic")->where(["id" => $item["id"]])->setInc("browse", 1);
		$label_ids = \think\Db::name("app_member_dynamic_label_ids")->where(["dynamic_id" => $item["id"]])->column("label_id");
		\think\Db::name("app_member_dynamic_label")->whereIn("id", $label_ids)->setInc("browse", 1);
		list($verify_code, $user) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, new \app\api\common\entity\MemberAppUserVerify());
		if ($verify_code == Code::success) {
			if (\think\Db::name("app_member_dynamic_browse_log")->where(["dynamic_id" => $item["id"], "uid" => $user["id"]])->count() == 0) {
				\think\Db::name("app_member_dynamic_browse_log")->insert(["appid" => $this->project["id"], "dynamic_id" => $item["id"], "uid" => $user["id"], "time" => time()]);
				\think\Db::name("app_member_dynamic")->where(["id" => $id])->setInc("browseUserNumber", 1);
				if (!empty($dynamic_config["reward"]["dynamic_share"]["contribute"])) {
				}
			} else {
				\think\Db::name("app_member_dynamic_browse_log")->where(["dynamic_id" => $item["id"], "uid" => $user["id"]])->update(["time" => time()]);
			}
		}
		$data = $this->get_dynamic_array($item, true);
		$this->response(Code::success, "获取成功", $data);
	}
	public function get_dynamic_comment_list()
	{
		$validate = \think\Validate::make(["dynamic_id" => "require"], ["dynamic_id.require" => "dynamic_id 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		$dynamic_id = $this->input["dynamic_id"];
		$sub_comment_length = $this->input["sub_comment_length"] ?? 5;
		$dynamic = \think\Db::name("app_member_dynamic")->where(["id" => $dynamic_id, "appid" => $this->project["id"]])->find();
		if (empty($dynamic)) {
			$this->response(10210, "动态ID不存在");
		}
		$page = $this->page_no;
		$limit = $this->page_size;
		$where = [];
		list($verify_code, $user) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, new \app\api\common\entity\MemberAppUserVerify());
		if ($verify_code == Code::success) {
			$where[] = ["", "exp", \think\Db::raw("status=1 or uid=" . $user["id"])];
		} else {
			$where[] = ["status", "=", 1];
		}
		$where[] = ["dynamic_id", "=", $dynamic_id];
		$where[] = ["level", "=", 1];
		$count = \think\Db::name("app_member_dynamic_comment")->where($where)->count();
		$pages = ceil($count / $limit);
		$list = \think\Db::name("app_member_dynamic_comment")->where($where)->page($page, $limit)->order(["likeNumber" => "desc", "id" => "asc"])->select();
		$data = [];
		foreach ($list as $item) {
			$data[] = $this->get_dynamic_comment_array($item, $sub_comment_length);
		}
		$this->response(Code::success, "获取成功", ["list" => $data, "pages" => $pages, "count" => $count, "page" => $page]);
	}
	private function get_dynamic_comment_array($item, $sub_comment_length) : array
	{
		$user = \think\Db::name("app_member_user")->where(["id" => $item["uid"]])->find();
		$replyList = [];
		list($verify_code, $self) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, new \app\api\common\entity\MemberAppUserVerify());
		$sub_comment_where[] = ["dynamic_id", "=", $item["dynamic_id"]];
		$sub_comment_where[] = ["pid", "=", $item["id"]];
		if ($verify_code == Code::success) {
			$sub_comment_where[] = ["", "exp", \think\Db::raw("status=1 or uid=" . $user["id"])];
		} else {
			$sub_comment_where[] = ["status", "=", 1];
		}
		$isLike = false;
		if (!empty($self)) {
			$like_log = \think\Db::name("dynamic_comment_like_log")->where(["uid" => $self["id"], "dynamic_id" => $item["dynamic_id"], "comment_id" => $item["id"]])->find();
			if (!empty($like_log)) {
				$isLike = true;
			}
		}
		$reply_list = \think\Db::name("app_member_dynamic_comment")->where($sub_comment_where)->limit($sub_comment_length)->order("id", "asc")->select();
		foreach ($reply_list as $reply_item) {
			$replyList[] = $this->get_dynamic_sub_comment_array($reply_item);
		}
		return ["id" => $item["id"], "dynamic_id" => $item["dynamic_id"], "status" => $item["status"], "uid" => $item["uid"], "level" => $item["level"], "pid" => $item["pid"], "content" => $item["content"], "addtime" => $item["addtime"], "type" => $item["type"], "user_info" => ["id" => $user["id"], "avatar" => $user["avatar"], "nickname" => $user["nickname"]], "allReply" => \think\Db::name("app_member_dynamic_comment")->where(["dynamic_id" => $item["dynamic_id"], "pid" => $item["id"]])->count(), "replyList" => $replyList, "isLike" => $isLike, "likeNumber" => \think\Db::name("app_member_dynamic_comment_like_log")->where(["dynamic_id" => $item["dynamic_id"], "comment_id" => $item["id"]])->count()];
	}
	public function get_dynamic_comment_info()
	{
		$validate = \think\Validate::make(["dynamic_id" => "require", "id" => "require"], ["dynamic_id.require" => "dynamic_id 不能为空！", "id.require" => "id 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		$id = $this->input["id"];
		$dynamic_id = $this->input["dynamic_id"];
		$item = \think\Db::name("app_member_dynamic_comment")->where(["dynamic_id" => $dynamic_id, "id" => $id, "appid" => $this->project["id"]])->find();
		if (empty($item)) {
			$this->response(10211, "评论ID不存在");
		}
		$data = $this->get_dynamic_comment_array($item, 0);
		$this->response(Code::success, "获取成功", $data);
	}
	public function get_dynamic_sub_comment_list()
	{
		$validate = \think\Validate::make(["dynamic_id" => "require", "pid" => "require"], ["dynamic_id.require" => "dynamic_id 不能为空！", "pid.require" => "pid 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		$pid = $this->input["pid"];
		$dynamic_id = $this->input["dynamic_id"];
		$dynamic = \think\Db::name("app_member_dynamic")->where(["id" => $dynamic_id, "appid" => $this->project["id"]])->find();
		if (empty($dynamic)) {
			$this->response(10212, "动态ID不存在");
		}
		$comment = \think\Db::name("app_member_dynamic_comment")->where(["dynamic_id" => $dynamic_id, "id" => $pid, "appid" => $this->project["id"]])->find();
		if (empty($comment)) {
			$this->response(10213, "评论ID不存在");
		}
		$where = [];
		$where[] = ["pid", "=", $pid];
		$page = $this->page_no;
		$limit = $this->page_size;
		$where[] = ["dynamic_id", "=", $dynamic_id];
		$count = \think\Db::name("app_member_dynamic_comment")->where($where)->count();
		$pages = ceil($count / $limit);
		$list = \think\Db::name("app_member_dynamic_comment")->where($where)->page($page, $limit)->order(["likeNumber" => "desc", "id" => "asc"])->select();
		$data = [];
		foreach ($list as $item) {
			$data[] = $this->get_dynamic_sub_comment_array($item);
		}
		$this->response(Code::success, "获取成功", ["list" => $data, "pages" => $pages, "count" => $count, "page" => $page]);
	}
	private function get_dynamic_sub_comment_array($item) : array
	{
		$user = \think\Db::name("app_member_user")->where(["id" => $item["uid"]])->find();
		list($verify_code, $self) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, new \app\api\common\entity\MemberAppUserVerify());
		$isLike = false;
		if ($verify_code == Code::success) {
			$like_log = \think\Db::name("app_member_dynamic_comment_like_log")->where(["uid" => $self["id"], "dynamic_id" => $item["dynamic_id"], "comment_id" => $item["id"]])->find();
			if (!empty($like_log)) {
				$isLike = true;
			}
		}
		$data = ["id" => $item["id"], "dynamic_id" => $item["dynamic_id"], "status" => $item["status"], "uid" => $item["uid"], "level" => $item["level"], "pid" => $item["pid"], "content" => $item["content"], "addtime" => $item["addtime"], "type" => $item["type"], "reply_id" => $item["reply_id"], "user_info" => ["id" => $user["id"], "avatar" => $user["avatar"], "nickname" => $user["nickname"]], "isLike" => $isLike, "likeNumber" => \think\Db::name("app_member_dynamic_comment_like_log")->where(["dynamic_id" => $item["dynamic_id"], "comment_id" => $item["id"]])->count()];
		if ($item["type"] == 1) {
			$reply_comment = \think\Db::name("app_member_dynamic_comment")->where(["id" => $item["reply_id"]])->find();
			$reply_user = \think\Db::name("app_member_user")->where(["id" => $reply_comment["uid"]])->find();
			$data["reply_info"] = ["comment_info" => ["id" => $reply_comment["id"], "uid" => $reply_comment["uid"], "level" => $reply_comment["level"], "pid" => $reply_comment["pid"], "content" => $reply_comment["content"], "addtime" => $reply_comment["addtime"], "type" => $reply_comment["type"], "reply_id" => $reply_comment["reply_id"]], "reply_user_info" => ["id" => $reply_user["id"], "avatar" => $reply_user["avatar"], "nickname" => $reply_user["nickname"]]];
		}
		return $data;
	}
	public function add_dynamic_comment()
	{
		$validate = \think\Validate::make(["dynamic_id" => "require", "content" => "require"], ["dynamic_id.require" => "dynamic_id 不能为空！", "content.require" => "内容 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		$dynamic_id = $this->input["dynamic_id"];
		$content = $this->input["content"];
		$pid = $this->input["pid"] ?? 0;
		$sub_comment_id = $this->input["sub_comment_id"] ?? 0;
		$dynamic_config = json_decode($this->project["member_app_config"], true)["dynamic_config"] ?? [];
		list($verify_code, $user) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, new \app\api\common\entity\MemberAppUserVerify());
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $user);
		}
		$last_time_comment = \think\Db::name("app_member_dynamic_comment")->where(["uid" => $user["id"], "appid" => $this->project["id"]])->order("id", "desc")->find();
		if (!empty($last_time_comment) && time() - $last_time_comment["addtime"] < (!empty($dynamic_config["comment_publish_interval"]) ? $dynamic_config["comment_publish_interval"] : 5)) {
			$this->response(10214, "评论太频繁,过一会再试吧");
		}
		if (\think\Db::name("app_member_dynamic_comment")->where([["uid", "=", $user["id"]], ["addtime", ">=", strtotime(date("Y-m-d"))], ["appid", "=", $this->project["id"]]])->count() >= (!empty($dynamic_config["comment_publish_maximum"]) ? $dynamic_config["comment_publish_maximum"] : 50)) {
			$this->response(Code::fail, "今日发布评论过多");
		}
		$dynamic = \think\Db::name("app_member_dynamic")->where(["id" => $dynamic_id, "appid" => $this->project["id"]])->find();
		$level = 1;
		$reply_id = 0;
		if (empty($dynamic)) {
			$this->response(10215, "动态ID不存在");
		}
		if ($sub_comment_id) {
			$sub_comment = \think\Db::name("app_member_dynamic_comment")->where(["dynamic_id" => $dynamic_id, "id" => $sub_comment_id, "appid" => $this->project["id"]])->find();
			if (empty($sub_comment)) {
				$this->response(10216, "评论ID不存在");
			} else {
				if ($sub_comment["level"] != 2) {
					$this->response(10217, "该评论非子级评论");
				}
			}
			$pid = $sub_comment["pid"];
			$level = 2;
			$reply_id = $sub_comment["id"];
		}
		if ($pid) {
			$comment = \think\Db::name("app_member_dynamic_comment")->where(["dynamic_id" => $dynamic_id, "id" => $pid, "appid" => $this->project["id"]])->find();
			if (empty($comment)) {
				$this->response(10216, "评论ID不存在");
			}
			$level = 2;
		}
		\think\Db::name("app_member_dynamic_comment")->insert(["appid" => $this->project["id"], "dynamic_id" => $dynamic_id, "uid" => $user["id"], "level" => $level, "pid" => $pid, "content" => $content, "type" => $sub_comment_id ? 1 : 0, "addtime" => time(), "reply_id" => $reply_id]);
		\think\Db::name("app_member_dynamic")->where(["id" => $dynamic_id])->setInc("chatNumber", 1);
		$this->response(Code::success, "评论成功");
	}
	public function dynamic_publish()
	{
		$validate = \think\Validate::make(["content" => "require", "title" => "require", "classify_id" => "require"], ["content.require" => "内容 不能为空！", "title.require" => "标题 不能为空！", "classify_id.require" => "分类 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		$title = $this->input["title"];
		$content = $this->input["content"];
		$classify_id = $this->input["classify_id"];
		$media_file_ids = isset($this->input["media_file_ids"]) && $this->input["media_file_ids"] != "" ? explode(",", $this->input["media_file_ids"]) : [];
		$share_file_ids = isset($this->input["share_file_ids"]) && $this->input["share_file_ids"] != "" ? explode(";", $this->input["share_file_ids"]) : [];
		$dynamic_config = json_decode($this->project["member_app_config"], true)["dynamic_config"] ?? [];
		list($verify_code, $user) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, new \app\api\common\entity\MemberAppUserVerify());
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $user);
		}
		\think\Db::startTrans();
		try {
			$isSystemAuthUnpaid = isSystemAuthUnpaid();
			if ($isSystemAuthUnpaid && \think\Db::name("app_member_dynamic")->where(["appid" => $this->project["id"]])->count() >= \app\common\model\FreeQuota::MemberDynamicLimitNum) {
				return ["code" => Code::fail, "msg" => "当前授权为基础版,一个应用最高动态数量上限为" . \app\common\model\FreeQuota::MemberDynamicLimitNum . \app\common\model\DefaultConfig::SystemAuthUnpaidSuffixText];
			}
			$last_time_dynamic_publish = \think\Db::name("app_member_dynamic")->where(["uid" => $user["id"], "appid" => $this->project["id"]])->order("id", "desc")->find();
			if (!empty($last_time_dynamic_publish) && time() - $last_time_dynamic_publish["addtime"] < (!empty($dynamic_config["comment_publish_interval"]) ? $dynamic_config["comment_publish_interval"] : 5)) {
				$this->response(10218, "发布太频繁,过一会再试吧");
			}
			if (\think\Db::name("app_member_dynamic")->where([["uid", "=", $user["id"]], ["addtime", ">=", strtotime(date("Y-m-d"))], ["appid", "=", $this->project["id"]]])->count() >= (!empty($dynamic_config["dynamic_publish_maximum"]) ? $dynamic_config["dynamic_publish_maximum"] : 10)) {
				$this->response(10219, "今日发布动态过多");
			}
			if (!$content) {
				$this->response(10220, "动态内容不能为空");
			}
			if ($classify_id && \think\Db::name("app_member_dynamic_classify")->where(["appid" => $this->project["id"], "id" => $classify_id])->count() == 0) {
				$this->response(10221, "分类不存在");
			}
			$carry_image = 0;
			$carry_video = 0;
			if (is_array($media_file_ids)) {
				foreach ($media_file_ids as $media_file_id) {
					$file = \think\Db::name("public_file_log")->where(["id" => $media_file_id])->find();
					if (!empty($file)) {
						\think\Db::name("public_file_log")->where(["id" => $file["id"]])->update(["overtime" => 0]);
					}
					if ($file["type"] == 0) {
						$carry_image = 1;
					}
					if ($file["type"] == 1) {
						$carry_video = 1;
					}
				}
			}
			$share_file_list = [];
			if (is_array($share_file_ids)) {
				foreach ($share_file_ids as $share_file_index => $share_file_item) {
					$share_file = explode(",", $share_file_item);
					if (!is_array($share_file) || count($share_file) != 2) {
						$this->response(10222, "第" . ($share_file_index + 1) . "个文件参数不正确");
					}
					if (!is_numeric($share_file[1]) || $share_file[1] < 0) {
						$this->response(10223, "第" . ($share_file_index + 1) . "个文件积分数量非法");
					}
					$file = \think\Db::name("public_file_log")->where(["id" => $share_file[0]])->find();
					if (!empty($file)) {
						\think\Db::name("public_file_log")->where(["id" => $file["id"]])->update(["overtime" => 0]);
						$share_file_list[] = ["file_id" => $file["id"], "file_name" => $file["name"], "file_size" => filesize($file["uri"]) ?: 0, "download_point_quantity" => $share_file[1]];
					}
				}
			}
			if (count($media_file_ids) == 2 && $carry_video && $carry_image) {
				$carry_image = 0;
			}
			$label_list = [];
			preg_match_all("/#([^#]{1,200})#/", $content, $labels, PREG_SET_ORDER);
			if ($labels) {
				foreach ($labels as $label_item) {
					if (isset($label_item[1])) {
						$label_list[] = $label_item[1];
					}
				}
			}
			if (isset($this->input["hidden_content"]) && isset($this->input["get_hidden_content_mode"]) && $this->input["get_hidden_content_mode"] == 1) {
				$validate = \think\Validate::make(["get_hidden_content_mode_point_quantity" => "require|number|integer|min:1"], ["get_hidden_content_mode_point_quantity.require" => "积分数量 不能为空！", "get_hidden_content_mode_point_quantity.number" => "积分数量 必须为数字！", "get_hidden_content_mode_point_quantity.integer" => "积分数量 必须为整数！", "get_hidden_content_mode_point_quantity.min" => "积分数量 最低不能小于1！"]);
				if (!$validate->check($this->input)) {
					$this->response(Code::fail, $validate->getError());
				}
			}
			$dynamic_id = \think\Db::name("app_member_dynamic")->insertGetId(["appid" => $this->project["id"], "uid" => $user["id"], "title" => $title, "content" => $content, "media_file_ids" => json_encode($media_file_ids), "share_file_list" => json_encode($share_file_list), "addtime" => time(), "cid" => $classify_id, "carry_image" => $carry_image, "carry_video" => $carry_video, "hidden_content" => $this->input["hidden_content"] ?? "", "get_hidden_content_mode" => $this->input["get_hidden_content_mode"] ?? "", "get_hidden_content_mode_point_quantity" => $this->input["get_hidden_content_mode_point_quantity"] ?? ""]);
			if (!empty($dynamic_config["reward"]["dynamic_publish"]["contribute"])) {
			}
			\think\Db::commit();
			$this->response(Code::success, "发布成功", ["dynamic_id" => $dynamic_id]);
		} catch (\Exception $e) {
			\think\Db::rollback();
			$this->response(Code::error, $e->getMessage());
		}
	}
	public function dynamic_like()
	{
		$validate = \think\Validate::make(["dynamic_id" => "require"], ["dynamic_id.require" => "dynamic_id 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		$dynamic_id = $this->input["dynamic_id"];
		list($verify_code, $user) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, new \app\api\common\entity\MemberAppUserVerify());
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $user);
		}
		$dynamic = \think\Db::name("app_member_dynamic")->where(["id" => $dynamic_id, "appid" => $this->project["id"]])->find();
		if (empty($dynamic)) {
			$this->response(10224, "动态ID不存在");
		}
		$log = \think\Db::name("app_member_dynamic_like_log")->where(["uid" => $user["id"], "dynamic_id" => $dynamic_id, "appid" => $this->project["id"]])->find();
		if (empty($log)) {
			\think\Db::name("app_member_dynamic_like_log")->insert(["appid" => $this->project["id"], "uid" => $user["id"], "dynamic_id" => $dynamic_id, "time" => time()]);
			\think\Db::name("app_member_dynamic")->where(["id" => $dynamic_id])->setInc("likeNumber", 1);
			$dynamic_config = json_decode($this->project["member_app_config"], true)["dynamic_config"] ?? [];
			if (!empty($dynamic_config["reward"]["dynamic_obtain_like"]["contribute"])) {
			}
			$this->response(Code::success, "点赞成功", ["isLike" => true]);
		} else {
			\think\Db::name("app_member_dynamic_like_log")->where(["uid" => $user["id"], "dynamic_id" => $dynamic_id, "appid" => $this->project["id"]])->delete();
			\think\Db::name("app_member_dynamic")->where(["id" => $dynamic_id])->setDec("likeNumber", 1);
			$dynamic_config = json_decode($this->project["member_app_config"], true)["dynamic_config"] ?? [];
			if (!empty($dynamic_config["reward"]["dynamic_obtain_like"]["contribute"])) {
			}
			$this->response(Code::success, "取消点赞成功", ["isLike" => false]);
		}
	}
	public function dynamic_collect()
	{
		$validate = \think\Validate::make(["dynamic_id" => "require"], ["dynamic_id.require" => "dynamic_id 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		$dynamic_id = $this->input["dynamic_id"];
		list($verify_code, $user) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, new \app\api\common\entity\MemberAppUserVerify());
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $user);
		}
		$dynamic = \think\Db::name("app_member_dynamic")->where(["id" => $dynamic_id, "appid" => $this->project["id"]])->find();
		if (empty($dynamic)) {
			$this->response(10225, "动态ID不存在");
		}
		$log = \think\Db::name("app_member_dynamic_collect_log")->where(["uid" => $user["id"], "dynamic_id" => $dynamic_id, "appid" => $this->project["id"]])->find();
		if (empty($log)) {
			\think\Db::name("app_member_dynamic_collect_log")->insert(["appid" => $this->project["id"], "uid" => $user["id"], "dynamic_id" => $dynamic_id, "time" => time()]);
			\think\Db::name("app_member_dynamic")->where(["id" => $dynamic_id])->setInc("collectNumber", 1);
			$dynamic_config = json_decode($this->project["member_app_config"], true)["dynamic_config"] ?? [];
			if (!empty($dynamic_config["reward"]["dynamic_obtain_collect"]["contribute"])) {
			}
			$this->response(Code::success, "收藏成功", ["isCollect" => true]);
		} else {
			\think\Db::name("app_member_dynamic_collect_log")->where(["uid" => $user["id"], "dynamic_id" => $dynamic_id, "appid" => $this->project["id"]])->delete();
			\think\Db::name("app_member_dynamic")->where(["id" => $dynamic_id])->setDec("collectNumber", 1);
			$dynamic_config = json_decode($this->project["member_app_config"], true)["dynamic_config"] ?? [];
			if (!empty($dynamic_config["reward"]["dynamic_obtain_collect"]["contribute"])) {
			}
			$this->response(Code::success, "取消收藏成功", ["isCollect" => false]);
		}
	}
	public function get_dynamic_collect_list()
	{
		$page = $this->page_no;
		$limit = $this->page_size;
		list($verify_code, $user) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, new \app\api\common\entity\MemberAppUserVerify());
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $user);
		}
		$where[] = ["appid", "=", $this->project["id"]];
		$where[] = ["uid", "=", $user["id"]];
		$count = \think\Db::name("app_member_dynamic_collect_log")->where($where)->count();
		$pages = ceil($count / $limit);
		$list = \think\Db::name("app_member_dynamic_collect_log")->where($where)->page($page, $limit)->order("id", "desc")->select();
		$data = [];
		foreach ($list as $item) {
			$dynamic_info = \think\Db::name("app_member_dynamic")->where(["id" => $item["dynamic_id"]])->find();
			$item["dynamic_info"] = empty($dynamic_info) ? [] : $this->get_dynamic_array($dynamic_info);
			$data[] = $item;
		}
		$this->response(Code::success, "获取成功", ["list" => $data, "pages" => $pages, "count" => $count, "page" => $page]);
	}
	public function get_dynamic_classify_list()
	{
		$classlist = \think\Db::name("app_member_dynamic_classify")->where(["appid" => $this->project["id"]])->order("sort", "desc")->select();
		$data = [];
		foreach ($classlist as $item) {
			$data[] = $item;
		}
		$this->response(Code::success, "获取成功", ["list" => $data]);
	}
	public function user_relation()
	{
		$validate = \think\Validate::make(["uid" => "require"], ["uid.require" => "uid 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		$uid = $this->input["uid"];
		list($verify_code, $user) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, new \app\api\common\entity\MemberAppUserVerify());
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $user);
		}
		if (\think\Db::name("app_member_user")->where(["appid" => $this->project["id"], "id" => $uid])->count() == 0) {
			$this->response(10226, "关注用户不存在");
		}
		if ($user["id"] == $uid) {
			$this->response(10227, "不能关注自己");
		}
		if (!\think\Db::name("app_member_user_relation")->where(["appid" => $this->project["id"], "uid" => $user["id"], "uuid" => $uid])->count()) {
			\think\Db::name("app_member_user_relation")->insert(["appid" => $this->project["id"], "uid" => $user["id"], "uuid" => $uid, "time" => time()]);
			$this->response(Code::success, "关注成功", ["isRelation" => true]);
		} else {
			\think\Db::name("app_member_user_relation")->where(["appid" => $this->project["id"], "uid" => $user["id"], "uuid" => $uid])->delete();
			$this->response(Code::success, "取消关注成功", ["isRelation" => false]);
		}
	}
	public function get_relation_list()
	{
		list($verify_code, $user) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, new \app\api\common\entity\MemberAppUserVerify());
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $user);
		}
		$where = [];
		$where[] = ["appid", "=", $this->project["id"]];
		$where[] = ["uid", "=", $user["id"]];
		$page = $this->page_no;
		$limit = $this->page_size;
		$count = \think\Db::name("app_member_user_relation")->where($where)->count();
		$pages = ceil($count / $limit);
		$list = \think\Db::name("app_member_user_relation")->where($where)->page($page, $limit)->order("id", "asc")->select();
		$data = [];
		foreach ($list as $item) {
			$item["user_info"] = \think\Db::name("app_member_user")->where(["id" => $item["uuid"]])->field("id,nickname,avatar")->find();
			$data[] = $item;
		}
		$this->response(Code::success, "获取成功", ["list" => $data, "pages" => $pages, "count" => $count, "page" => $page]);
	}
	public function get_someone_relation_list()
	{
		$validate = \think\Validate::make(["uid" => "require"], ["uid.require" => "uid 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		$uid = $this->input["uid"];
		list($verify_code, $user) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, new \app\api\common\entity\MemberAppUserVerify());
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $user);
		}
		$where = [];
		$where[] = ["appid", "=", $this->project["id"]];
		$where[] = ["uid", "=", $uid];
		$page = $this->page_no;
		$limit = $this->page_size;
		$count = \think\Db::name("app_member_user_relation")->where($where)->count();
		$pages = ceil($count / $limit);
		$list = \think\Db::name("app_member_user_relation")->where($where)->page($page, $limit)->order("id", "asc")->select();
		$data = [];
		foreach ($list as $item) {
			$item["user_info"] = \think\Db::name("app_member_user")->where(["id" => $item["uuid"]])->field("id,nickname,avatar")->find();
			$data[] = $item;
		}
		$this->response(Code::success, "获取成功", ["list" => $data, "pages" => $pages, "count" => $count, "page" => $page]);
	}
	public function get_fans_list()
	{
		list($verify_code, $user) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, new \app\api\common\entity\MemberAppUserVerify());
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $user);
		}
		$where = [];
		$where[] = ["appid", "=", $this->project["id"]];
		$where[] = ["uuid", "=", $user["id"]];
		$page = $this->page_no;
		$limit = $this->page_size;
		$count = \think\Db::name("app_member_user_relation")->where($where)->count();
		$pages = ceil($count / $limit);
		$list = \think\Db::name("app_member_user_relation")->where($where)->page($page, $limit)->order("id", "asc")->select();
		$data = [];
		foreach ($list as $item) {
			$item["user_info"] = \think\Db::name("app_member_user")->where(["id" => $item["uid"]])->field("id,nickname,avatar")->find();
			$data[] = $item;
		}
		$this->response(Code::success, "获取成功", ["list" => $data, "pages" => $pages, "count" => $count, "page" => $page]);
	}
	public function get_someone_fans_list()
	{
		$validate = \think\Validate::make(["uid" => "require"], ["uid.require" => "uid 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		$uid = $this->input["uid"];
		list($verify_code, $user) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, new \app\api\common\entity\MemberAppUserVerify());
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $user);
		}
		$where = [];
		$where[] = ["appid", "=", $this->project["id"]];
		$where[] = ["uuid", "=", $uid];
		$page = $this->page_no;
		$limit = $this->page_size;
		$count = \think\Db::name("app_member_user_relation")->where($where)->count();
		$pages = ceil($count / $limit);
		$list = \think\Db::name("app_member_user_relation")->where($where)->page($page, $limit)->order("id", "asc")->select();
		$data = [];
		foreach ($list as $item) {
			$item["user_info"] = \think\Db::name("app_member_user")->where(["id" => $item["uid"]])->field("id,nickname,avatar")->find();
			$data[] = $item;
		}
		$this->response(Code::success, "获取成功", ["list" => $data, "pages" => $pages, "count" => $count, "page" => $page]);
	}
	public function dynamic_comment_like()
	{
		$validate = \think\Validate::make(["dynamic_id" => "require", "comment_id" => "require"], ["dynamic_id.require" => "dynamic_id 不能为空！", "comment_id.require" => "comment_id 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		$dynamic_id = $this->input["dynamic_id"];
		$comment_id = $this->input["comment_id"];
		list($verify_code, $user) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, new \app\api\common\entity\MemberAppUserVerify());
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $user);
		}
		$dynamic = \think\Db::name("app_member_dynamic")->where(["id" => $dynamic_id, "appid" => $this->project["id"]])->find();
		if (empty($dynamic)) {
			$this->response(10228, "动态ID不存在");
		}
		$comment = \think\Db::name("app_member_dynamic_comment")->where(["id" => $comment_id, "dynamic_id" => $dynamic_id, "appid" => $this->project["id"]])->find();
		if (empty($comment)) {
			$this->response(10229, "评论ID不存在");
		}
		$log = \think\Db::name("app_member_dynamic_comment_like_log")->where(["uid" => $user["id"], "dynamic_id" => $dynamic_id, "comment_id" => $comment_id, "appid" => $this->project["id"]])->find();
		if (empty($log)) {
			\think\Db::name("app_member_dynamic_comment_like_log")->insert(["appid" => $this->project["id"], "uid" => $user["id"], "dynamic_id" => $dynamic_id, "comment_id" => $comment_id, "time" => time()]);
			\think\Db::name("app_member_dynamic_comment")->where(["id" => $comment_id])->setInc("likeNumber", 1);
			$this->response(Code::success, "点赞成功", ["isLike" => true]);
		} else {
			\think\Db::name("app_member_dynamic_comment_like_log")->where(["uid" => $user["id"], "dynamic_id" => $dynamic_id, "appid" => $this->project["id"], "comment_id" => $comment_id])->delete();
			\think\Db::name("app_member_dynamic_comment")->where(["id" => $comment_id])->setDec("likeNumber", 1);
			$this->response(Code::success, "取消点赞成功", ["isLike" => false]);
		}
	}
	public function get_dynamic_label_list()
	{
		$where[] = ["appid", "=", $this->project["id"]];
		if (!empty($this->input["name"])) {
			$where[] = ["name", "like", "%" . $this->input["name"] . "%"];
		}
		$page = $this->page_no;
		$limit = $this->page_size;
		$count = \think\Db::name("app_member_dynamic_label")->where($where)->count();
		$pages = ceil($count / $limit);
		$list = \think\Db::name("app_member_dynamic_label")->where($where)->page($page, $limit)->order("browse", "desc")->select();
		$data = [];
		foreach ($list as $item) {
			$item["user_info"] = \think\Db::name("app_member_user")->where(["id" => $item["uid"]])->field("id,nickname,avatar")->find();
			$data[] = $item;
		}
		$this->response(Code::success, "获取成功", ["list" => $data, "pages" => $pages, "count" => $count, "page" => $page]);
	}
	public function revise_background()
	{
		$validate = \think\Validate::make(["file_id" => "require"], ["file_id.require" => "file_id 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		$file_id = $this->input["file_id"];
		list($verify_code, $user) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, new \app\api\common\entity\MemberAppUserVerify());
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $user);
		}
		$file = \think\Db::name("public_file_log")->where(["id" => $file_id])->find();
		if (!empty($file)) {
			if ($file["type"] == 0) {
				if (empty($file["channel"])) {
					$url = get_static_resources_url($file["uri"]);
				} else {
					$url = $file["url"];
				}
				\think\Db::name("public_file_log")->where(["id" => $file["id"]])->update(["overtime" => 0]);
				\think\Db::name("app_member_user")->where(["id" => $user["id"]])->update(["background" => $url]);
				$this->response(Code::success, "修改成功");
			} else {
				$this->response(10230, "文件类型错误");
			}
		} else {
			$this->response(10231, "文件ID不存在");
		}
	}
	public function del_dynamic()
	{
		$validate = \think\Validate::make(["id" => "require"], ["id.require" => "id 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		$id = $this->input["id"];
		list($verify_code, $user) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, new \app\api\common\entity\MemberAppUserVerify());
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $user);
		}
		$row = \think\Db::name("app_member_dynamic")->where(["id" => $id])->where(["appid" => $this->project["id"], "uid" => $user["id"]])->find();
		if (empty($row)) {
			$this->response(10232, "动态id不存在");
		}
		$del = \think\Db::name("app_member_dynamic")->where(["id" => $id])->delete();
		if ($del) {
			\think\Db::name("app_member_dynamic_collect_log")->where(["dynamic_id" => $id])->delete();
			$this->response(Code::success, "删除成功");
		} else {
			$this->response(Code::error, "删除失败");
		}
	}
	public function del_dynamic_comment()
	{
		$validate = \think\Validate::make(["id" => "require"], ["id.require" => "id 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		$id = $this->input["id"];
		list($verify_code, $user) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, new \app\api\common\entity\MemberAppUserVerify());
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $user);
		}
		$row = \think\Db::name("app_member_dynamic_comment")->where(["id" => $id])->where(["appid" => $this->project["id"], "uid" => $user["id"]])->find();
		if (empty($row)) {
			$this->response(10233, "评论id不存在");
		}
		$del = \think\Db::name("app_member_dynamic_comment")->where(["id" => $id])->delete();
		if ($del) {
			\think\Db::name("app_member_dynamic")->where(["id" => $row["dynamic_id"]])->setDec("chatNumber", 1);
			$this->response(Code::success, "删除成功");
		} else {
			$this->response(Code::fail, "删除失败");
		}
	}
	public function get_login_sms_code()
	{
		$validate = \think\Validate::make(["phone" => "require"], ["phone.require" => "手机号 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		list($channel_type, $config) = get_sms_config();
		$res = \app\common\Sms::get_verification_code($channel_type, $config, $this->input["phone"], ["type" => \app\common\model\VerificationLog::SmsLog_MemberUserLogin, "other" => ""]);
		if ($res["code"] == 10000) {
			$this->response(Code::success, $res["msg"]);
		} else {
			$this->response($res["code"], $res["msg"]);
		}
	}
	public function phone_login()
	{
		$validate = \think\Validate::make(["phone" => "require", "code" => "require"], ["phone.require" => "手机号码 不能为空！", "code.require" => "验证码 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		$member_app_config = json_decode($this->project["member_app_config"], true);
		$isSystemAuthUnpaid = isSystemAuthUnpaid();
		if ($isSystemAuthUnpaid && \think\Db::name("app_member_user")->where(["appid" => $this->project["id"]])->count() >= \app\common\model\FreeQuota::MemberAppUserQuota) {
			return ["code" => Code::fail, "msg" => "当前授权为基础版,一个应用最多只能注册" . \app\common\model\FreeQuota::MemberAppUserQuota . "个用户" . \app\common\model\DefaultConfig::SystemAuthUnpaidSuffixText];
		}
		\think\Db::startTrans();
		try {
			$code_log = \think\Db::name("verification_code_log")->where([["account", "=", $this->input["phone"]], ["mode", "=", \app\common\model\VerificationLog::Mode_Sms], ["type", "=", \app\common\model\VerificationLog::SmsLog_MemberUserLogin], ["other", "=", ""]])->order("id", "desc")->find();
			if (empty($code_log) || $code_log["code"] != $this->input["code"]) {
				$this->response(10238, "手机验证码错误");
			}
			if (\time() > $code_log["expire"]) {
				$this->response(10239, "手机验证码过期");
			}
			if ($code_log["status"] == 1) {
				$this->response(10240, "手机验证码已失效");
			}
			\think\Db::name("verification_code_log")->where(["id" => $code_log["id"]])->update(["status" => 1]);
			$account = $this->input["phone"];
			$user = \think\Db::name("app_member_user")->where(["appid" => $this->project["id"], "phone" => $this->input["phone"]])->find();
			if (empty($user)) {
				if (!empty($member_app_config["register_config"]["phone_close"])) {
					$this->response(10241, "未开放新用户注册");
				}
				$avatar = $this->input["avatar"] ?? "";
				if (is_numeric($avatar)) {
					$file = \think\Db::name("public_upload_log")->where(["id" => $avatar])->find();
					if ($file) {
						if (empty($file["channel"])) {
							$avatar = get_static_resources_url($file["uri"]);
						} else {
							$avatar = $file["url"];
						}
						\think\Db::name("public_upload_log")->where(["id" => $avatar])->update(["overtime" => 0]);
					}
				}
				$data = ["appid" => $this->project["id"], "account" => $account, "phone" => $account, "machine_code" => $this->input["machine_code"], "password" => GeneratePassword("123456"), "nickname" => $this->input["nickname"] ?? "昵称未设置", "avatar" => $avatar, "register_ip" => $this->client_ip, "addtime" => time()];
				$user = $this->user_register_handle($data);
			}
			$data = $this->login_logic_handle($user);
			\think\Db::commit();
			$this->response(Code::success, "登录成功", $data);
		} catch (\Exception $e) {
			\think\Db::rollback();
			$this->response(Code::error, "登录失败：" . $e->getMessage());
		}
	}
	private function user_register_handle($data)
	{
		$user_default_level = \think\Db::name("app_member_user_level")->where(["appid" => $this->project["id"], "is_default" => 1])->find();
		$data["level_id"] = $user_default_level["id"] ?? 0;
		$uid = \think\Db::name("app_member_user")->insertGetId($data);
		$member_app_config = json_decode($this->project["member_app_config"], true);
		if (!empty($member_app_config["register_config"]["register_code_verify"])) {
			if (empty($this->input["register_code"])) {
				$this->response(10242, "后台开启注册码验证,需要提交注册码参数register_code");
			}
			$card = \think\Db::name("app_member_card")->where(["appid" => $this->project["id"], "card" => $this->input["register_code"], "type" => \app\common\model\CardType::RegisterCode[0]])->find();
			if (!$card) {
				$this->response(10243, "注册码不存在");
			}
			if ($card["status"] == 1) {
				$this->response(10244, "注册码已使用");
			}
			\think\Db::name("app_member_card")->where(["id" => $card["id"]])->update(["status" => 1, "usetime" => time(), "useuid" => $uid]);
		}
		\app\common\server\StatisticsData::increases($this->project["id"], \app\common\model\AppData::MemberAppUserRegister, 1);
		if (!empty($member_app_config["register_config"]["give"]["point"])) {
			\app\api\common\member\Finance::set($uid, "point", $member_app_config["register_config"]["give"]["point"], 0, "注册赠送", \app\common\model\MemberAppModel::UserPointLogSourceRegisterGive);
		}
		if (!empty($member_app_config["register_config"]["give"]["viptime"]["value"]) && isset($member_app_config["register_config"]["give"]["viptime"]["type"])) {
			$viptime = \app\common\helper\Time::computing_time($member_app_config["register_config"]["give"]["viptime"]["type"], $member_app_config["register_config"]["give"]["viptime"]["value"], 0);
			\app\api\common\member\Finance::set($uid, "viptime", $viptime, 0, "注册赠送", \app\common\model\MemberAppModel::UserVipTimeLogSourceRegisterGive);
		}
		if (!empty($member_app_config["register_config"]["give"]["growth"])) {
			\app\api\common\member\Finance::set($uid, "growth", $member_app_config["register_config"]["give"]["growth"], 0, "注册赠送", \app\common\model\MemberAppModel::UserGrowthLogSourceRegisterGive);
		}
		$user = \think\Db::name("app_member_user")->where("id", $uid)->find();
		return $user;
	}
	public function get_reset_password_phone_code()
	{
		$validate = \think\Validate::make(["phone" => "require"], ["phone.require" => "手机号 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		$user = \think\Db::name("app_member_user")->where(["appid" => $this->project["id"], "phone" => $this->input["phone"]])->find();
		if (empty($user)) {
			$this->response(10245, "您的手机号未注册或绑定用户账号");
		}
		list($channel_type, $config) = get_sms_config();
		$res = \app\common\Sms::get_verification_code($channel_type, $config, $this->input["phone"], ["type" => \app\common\model\VerificationLog::SmsLog_MemberUserResetPassword, "other" => $user["id"]]);
		if ($res["code"] == 10000) {
			$this->response(Code::success, $res["msg"]);
		} else {
			$this->response($res["code"], $res["msg"]);
		}
	}
	public function phone_verify_reset_password()
	{
		$validate = \think\Validate::make(["phone" => "require", "code" => "require", "new_password" => "require"], ["phone.require" => "手机号 不能为空！", "code.require" => "验证码 不能为空！", "new_password.require" => "新密码 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		\think\Db::startTrans();
		try {
			$code_log = \think\Db::name("verification_code_log")->where([["account", "=", $this->input["phone"]], ["mode", "=", \app\common\model\VerificationLog::Mode_Sms], ["type", "=", \app\common\model\VerificationLog::SmsLog_MemberUserLogin], ["other", "=", ""]])->order("id", "desc")->find();
			if (empty($code_log) || $code_log["code"] != $this->input["code"]) {
				$this->response(10246, "验证码错误");
			}
			if (\time() > $code_log["expire"]) {
				$this->response(10247, "验证码过期");
			}
			if ($code_log["status"] == 1) {
				$this->response(10248, "验证码已失效");
			}
			\think\Db::name("verification_code_log")->where(["id" => $code_log["id"]])->update(["status" => 1]);
			$user = \think\Db::name("app_member_user")->where(["appid" => $this->project["id"], "phone" => $this->input["phone"]])->find();
			if (empty($user)) {
				$this->response(10249, "您的手机号未注册或绑定用户账号");
			}
			memberUserPasswordChange($user, $this->input["new_password"]);
			\think\Db::commit();
			$this->response(Code::success, "重置成功");
		} catch (\Exception $e) {
			\think\Db::rollback();
			$this->response(Code::error, $e->getMessage());
		}
	}
	public function get_card_info()
	{
		$validate = \think\Validate::make(["card" => "require"], ["card.require" => "卡密 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		$card = findCardCaseSensitive("app_member_card", ["appid" => $this->project["id"], "card" => $this->input["card"]]);
		if (empty($card)) {
			$this->response(10250, "卡密不存在");
		}
		$this->response(Code::success, "获取成功", ["card" => $card["card"], "type" => $card["type"], "time_type" => $card["time_type"], "value" => $card["value"], "addtime" => $card["addtime"], "usetime" => $card["usetime"], "status" => $card["status"], "agent_id" => $card["agent_id"], "batch_id" => $card["batch_id"], "useuid" => $card["useuid"]]);
	}
	public function get_phone_change_binding_code()
	{
		$validate = \think\Validate::make(["phone" => "require"], ["phone.require" => "手机号 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		list($verify_code, $user) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, new \app\api\common\entity\MemberAppUserVerify());
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $user);
		}
		$user = \think\Db::name("app_member_user")->where(["appid" => $this->project["id"], "phone" => $this->input["phone"]])->find();
		if (empty($user)) {
		}
		list($channel_type, $config) = get_sms_config();
		$res = \app\common\Sms::get_verification_code($channel_type, $config, $this->input["phone"], ["type" => \app\common\model\VerificationLog::SmsLog_MemberUserPhoneChangeBinding, "other" => $user["id"]]);
		if ($res["code"] == 10000) {
			$this->response(Code::success, $res["msg"]);
		} else {
			$this->response($res["code"], $res["msg"]);
		}
	}
	public function phone_change_binding()
	{
		$validate = \think\Validate::make(["phone" => "require", "code" => "require"], ["phone.require" => "手机号 不能为空！", "code.require" => "验证码 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		list($verify_code, $user) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, new \app\api\common\entity\MemberAppUserVerify());
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $user);
		}
		$code_log = \think\Db::name("verification_code_log")->where([["account", "=", $this->input["phone"]], ["mode", "=", \app\common\model\VerificationLog::Mode_Sms], ["type", "=", \app\common\model\VerificationLog::SmsLog_MemberUserPhoneChangeBinding], ["other", "=", $user["id"]]])->order("id", "desc")->find();
		if (empty($code_log) || $code_log["code"] != $this->input["code"]) {
			$this->response(10270, "验证码错误");
		}
		if (\time() > $code_log["expire"]) {
			$this->response(10271, "验证码过期");
		}
		if ($code_log["status"] == 1) {
			$this->response(10272, "验证码已失效");
		}
		\think\Db::name("verification_code_log")->where(["id" => $code_log["id"]])->update(["status" => 1]);
		try {
			\think\Db::startTrans();
			$row = \think\Db::name("app_member_user")->where(["phone" => $this->input["phone"], "appid" => $user["appid"]])->find();
			if (!empty($row) && $row["id"] != $user["id"]) {
				$this->response(10251, "该手机号已被其他用户绑定");
			}
			\think\Db::name("app_member_user")->where(["id" => $user["id"]])->update(["phone" => $this->input["phone"]]);
			\think\Db::commit();
			$this->response(Code::success, "绑定成功");
		} catch (\Exception $e) {
			\think\Db::rollback();
			$this->response(Code::error, "失败：" . $e->getMessage());
		}
	}
	public function get_phone_unbinding_code()
	{
		list($verify_code, $user) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, new \app\api\common\entity\MemberAppUserVerify());
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $user);
		}
		if (empty($user["phone"])) {
			$this->response(10269, "您的账号未绑定手机号,无需解绑");
		}
		list($channel_type, $config) = get_sms_config();
		$res = \app\common\Sms::get_verification_code($channel_type, $config, $user["phone"], ["type" => \app\common\model\VerificationLog::SmsLog_MemberUserPhoneUnbinding, "other" => $user["id"]]);
		if ($res["code"] == 10000) {
			$this->response(Code::success, $res["msg"]);
		} else {
			$this->response($res["code"], $res["msg"]);
		}
	}
	public function phone_unbinding()
	{
		$validate = \think\Validate::make(["code" => "require"], ["code.require" => "验证码 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		list($verify_code, $user) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, new \app\api\common\entity\MemberAppUserVerify());
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $user);
		}
		if (!$user["phone"]) {
			$this->response(10252, "账号未绑定手机号无需解绑");
		}
		$code_log = \think\Db::name("verification_code_log")->where([["account", "=", $user["phone"]], ["mode", "=", \app\common\model\VerificationLog::Mode_Sms], ["type", "=", \app\common\model\VerificationLog::SmsLog_MemberUserPhoneUnbinding], ["other", "=", $user["id"]]])->order("id", "desc")->find();
		if (empty($code_log) || $code_log["code"] != $this->input["code"]) {
			$this->response(10273, "验证码错误");
		}
		if (\time() > $code_log["expire"]) {
			$this->response(10274, "验证码过期");
		}
		if ($code_log["status"] == 1) {
			$this->response(10275, "验证码已失效");
		}
		\think\Db::name("verification_code_log")->where(["id" => $code_log["id"]])->update(["status" => 1]);
		\think\Db::name("app_member_user")->where(["id" => $user["id"]])->update(["phone" => ""]);
		$this->response(Code::success, "解绑成功");
	}
	public function dynamic_unlock_hidden_content()
	{
		$validate = \think\Validate::make(["dynamic_id" => "require"], ["dynamic_id.require" => "dynamic_id 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		$dynamic_id = $this->input["dynamic_id"];
		list($verify_code, $user) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, new \app\api\common\entity\MemberAppUserVerify());
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $user);
		}
		$dynamic = \think\Db::name("app_member_dynamic")->where(["id" => $dynamic_id, "appid" => $this->project["id"]])->find();
		if (empty($dynamic)) {
			$this->response(10253, "动态ID不存在");
		}
		$is_already_get_hidden_content = $this->dynamic_check_is_already_get_hidden_content($verify_code, $user, $dynamic);
		if ($is_already_get_hidden_content) {
		} else {
			if ($dynamic["get_hidden_content_mode"] == 0) {
				$this->response(10254, "您可以评论内容进行解锁");
			} elseif ($dynamic["get_hidden_content_mode"] == 1) {
				if ($user["point"] < $dynamic["get_hidden_content_mode_point_quantity"]) {
					$this->response(10255, "您的积分不足");
				}
				\app\api\common\member\Finance::set($user, "point", $dynamic["get_hidden_content_mode_point_quantity"], 1, "解锁动态隐藏内容消耗(动态ID:{$dynamic["id"]},标题:{$dynamic["title"]})", \app\common\model\MemberAppModel::UserPointLogSourceDynamicGetHiddenContentDeduct, $dynamic_id);
				if ($dynamic["get_hidden_content_mode_point_quantity"] > 0) {
					\app\api\common\member\Finance::set($dynamic["uid"], "point", $dynamic["get_hidden_content_mode_point_quantity"], 0, "动态被解锁隐藏内容收益(动态ID:{$dynamic["id"]},标题:{$dynamic["title"]})", \app\common\model\MemberAppModel::UserPointLogSourcePushDynamicGetHiddenContentIncrease, $dynamic_id);
				}
			}
		}
		$this->response(Code::success, "解锁成功", ["hidden_content" => $dynamic["hidden_content"]]);
	}
	private function dynamic_check_is_already_get_hidden_content($verify_code, $self, $item) : bool
	{
		$result = false;
		if ($verify_code == Code::success) {
			if ($item["get_hidden_content_mode"] == 0 && \think\Db::name("app_member_dynamic_comment")->where(["dynamic_id" => $item["id"], "uid" => $self["id"]])->count() > 0) {
				$result = true;
			}
			if ($item["get_hidden_content_mode"] == 1 && \think\Db::name("app_member_user_finance_log")->where(["extra_data" => $item["id"], "uid" => $self["id"], "source" => \app\common\model\MemberAppModel::UserPointLogSourceDynamicGetHiddenContentDeduct])->count() > 0) {
				$result = true;
			}
		}
		return $result;
	}
	public function dynamic_unlock_share_file_download()
	{
		$validate = \think\Validate::make(["dynamic_id" => "require", "share_file_id" => "require"], ["dynamic_id.require" => "dynamic_id 不能为空！", "share_file_id.require" => "share_file_id 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		$dynamic_id = $this->input["dynamic_id"];
		list($verify_code, $user) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, new \app\api\common\entity\MemberAppUserVerify());
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $user);
		}
		$dynamic = \think\Db::name("app_member_dynamic")->where(["id" => $dynamic_id, "appid" => $this->project["id"]])->find();
		if (empty($dynamic)) {
			$this->response(10256, "动态ID不存在");
		}
		$share_file_list = json_decode($dynamic["share_file_list"]) ?: [];
		$share_file = null;
		foreach ($share_file_list as $share_file_index => $share_file_item) {
			if ($share_file_item == $this->input["share_file_id"]) {
				$share_file = $share_file_item;
			}
		}
		if (!$share_file) {
			$this->response(10257, "共享文件不存在");
		}
		$is_already_get_share_file = $this->dynamic_check_is_already_get_share_file($verify_code, $user, $this->input["share_file_id"]);
		if ($is_already_get_share_file) {
			$this->response(10258, "您已解锁该文件下载权限无需再次解锁");
		} else {
			$download_point_quantity = $share_file["download_point_quantity"] ?: 0;
			if ($user["point"] < $download_point_quantity) {
				$this->response(10259, "您的积分不足");
			}
			\app\api\common\member\Finance::set($user, "point", $download_point_quantity, 1, "解锁动态文件下载消耗(动态ID:{$dynamic["id"]},标题:{$dynamic["title"]},文件名:{$share_file["file_name"]})", \app\common\model\MemberAppModel::UserPointLogSourceDynamicGetHiddenContentDeduct, $this->input["share_file_id"]);
			if ($download_point_quantity > 0) {
				\app\api\common\member\Finance::set($dynamic["uid"], "point", $dynamic["get_hidden_content_mode_point_quantity"], 0, "动态被解锁文件下载收益(动态ID:{$dynamic["id"]},标题:{$dynamic["title"]},文件名:{$share_file["file_name"]})", \app\common\model\MemberAppModel::UserPointLogSourcePushDynamicGetShareFileIncrease, $this->input["share_file_id"]);
			}
		}
		$this->response(Code::success, "解锁成功");
	}
	private function dynamic_check_is_already_get_share_file($verify_code, $self, $file_id) : bool
	{
		$result = false;
		if ($verify_code == Code::success) {
			if (\think\Db::name("app_member_user_finance_log")->where(["extra_data" => $file_id, "uid" => $self["id"], "source" => \app\common\model\MemberAppModel::UserPointLogSourceDynamicGetShareFileDeduct])->count() > 0) {
				$result = true;
			}
		}
		return $result;
	}
	public function get_dynamic_share_file_item_download_url()
	{
		$validate = \think\Validate::make(["dynamic_id" => "require", "share_file_id" => "require"], ["dynamic_id.require" => "dynamic_id 不能为空！", "share_file_id.require" => "share_file_id 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		$dynamic_id = $this->input["dynamic_id"];
		list($verify_code, $user) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, new \app\api\common\entity\MemberAppUserVerify());
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $user);
		}
		$dynamic = \think\Db::name("app_member_dynamic")->where(["id" => $dynamic_id, "appid" => $this->project["id"]])->find();
		if (empty($dynamic)) {
			$this->response(10260, "动态ID不存在");
		}
		$share_file_list = json_decode($dynamic["share_file_list"]) ?: [];
		$share_file = null;
		foreach ($share_file_list as $share_file_index => $share_file_item) {
			if ($share_file_item == $this->input["share_file_id"]) {
				$share_file = $share_file_item;
			}
		}
		if (!$share_file) {
			$this->response(10261, "共享文件不存在");
		}
		$is_already_get_share_file = $this->dynamic_check_is_already_get_share_file($verify_code, $user, $this->input["share_file_id"]);
		if (!$is_already_get_share_file) {
			$this->response(10262, "您没有获得该文件的下载权限");
		}
		$file_download_url = get_dynamic_share_file_download_url($this->input["share_file_id"]);
		$this->response(Code::success, "获取成功，链接10分钟内有效", ["file_download_url" => $file_download_url]);
	}
	public function get_account_finance_log()
	{
		list($verify_code, $user) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, new \app\api\common\entity\MemberAppUserVerify());
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $user);
		}
		$where = [];
		$where[] = ["appid", "=", $this->project["id"]];
		$where[] = ["uid", "=", $user["id"]];
		if (isset($this->input["field"]) && $this->input["field"] != "") {
			$where[] = ["field", "=", $user["field"]];
		}
		if (isset($this->input["type"]) && $this->input["type"] != "") {
			$where[] = ["type", "=", $user["type"]];
		}
		if (isset($this->input["source"]) && $this->input["source"] != "") {
			$where[] = ["source", "=", $user["source"]];
		}
		$page = $this->page_no;
		$limit = $this->page_size;
		$count = \think\Db::name("app_member_user_finance_log")->where($where)->count();
		$pages = ceil($count / $limit);
		$list = \think\Db::name("app_member_user_finance_log")->where($where)->page($page, $limit)->order("id", "desc")->select();
		$data = [];
		foreach ($list as $item) {
			$data[] = $item;
		}
		$this->response(Code::success, "获取成功", $data, ["count", $count], ["pages", $pages]);
	}
	public function logout()
	{
		$verify_user = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, new \app\api\common\entity\MemberAppUserVerify());
		$verify_code = $verify_user[0];
		$user = $verify_user[1];
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $user);
		}
		$login_machine = $verify_user[2];
		\think\Db::startTrans();
		try {
			\think\Db::name("app_member_user_login_machine")->where(["id" => $login_machine["id"]])->update(["token_status" => 3]);
			\think\Db::commit();
			$this->response(Code::success, "操作成功");
		} catch (\Exception $e) {
			\think\Db::rollback();
			$this->response(Code::error, $e->getMessage());
		}
	}
	public function disable()
	{
		list($verify_code, $user) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, new \app\api\common\entity\MemberAppUserVerify());
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $user);
		}
		\think\Db::name("app_member_user")->where(["id" => $user["id"]])->update(["disable" => 1]);
		$this->response(Code::success, "操作成功");
	}
	public function create_renewal_order()
	{
		$validate = \think\Validate::make(["pay_type" => "require|in:1,2,3", "type" => "require", "value" => "require|number|>=:1", "user" => "require"], ["pay_type.require" => "请选择支付方式", "type.require" => "开通/续费类型 不能为空", "value.require" => "开通/续费面值 不能为空", "user.require" => "开通/续费用户 不能为空"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		$result = \app\common\service\AppCardBuy::createRenewalOrder($this->input);
		if ($result["code"] != 1) {
			$this->response(Code::fail, $result["msg"]);
		}
		$pay_url = getsiteurl() . "/index/buy/pay/order_id/" . $result["data"]["id"];
		if (!empty($this->input["return_url"])) {
			$pay_url .= "?return_url=" . urlencode($this->input["return_url"]);
		}
		$this->response(Code::success, $result["msg"], array_merge($result["data"], ["pay_url" => $pay_url]));
	}
	public function get_binding_mail_code()
	{
		$validate = \think\Validate::make(["mail" => "require"], ["mail.require" => "邮箱mail 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		list($verify_code, $user) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, new \app\api\common\entity\MemberAppUserVerify());
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $user);
		}
		$user = \think\Db::name("app_member_user")->where(["appid" => $this->project["id"], "mail" => $this->input["mail"]])->find();
		if (!empty($user)) {
		}
		$res = \app\common\Mail::get_verification_code(json_decode($this->project["mail_config"], true), $this->input["mail"], "【{$this->project["name"]}】 - 账号邮箱绑定验证码", ["type" => \app\common\model\VerificationLog::MailLog_MemberUserBindingMail, "other" => $user["id"]]);
		if ($res["code"] == 10000) {
			$this->response(Code::success, $res["msg"]);
		} else {
			$this->response($res["code"], $res["msg"]);
		}
	}
	public function get_unbinding_mail_code()
	{
		list($verify_code, $user) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, new \app\api\common\entity\MemberAppUserVerify());
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $user);
		}
		$user = \think\Db::name("app_member_user")->where(["appid" => $this->project["id"], "mail" => $this->input["mail"]])->find();
		if (empty($user["mail"])) {
			$this->response(10276, "您的账号未绑定邮箱，无需解绑");
		}
		$res = \app\common\Mail::get_verification_code(json_decode($this->project["mail_config"], true), $user["mail"], "【{$this->project["name"]}】 - 账号邮箱解绑验证码", ["type" => \app\common\model\VerificationLog::MailLog_MemberUserUnbindingMail, "other" => $user["id"]]);
		if ($res["code"] == 10000) {
			$this->response(Code::success, $res["msg"]);
		} else {
			$this->response($res["code"], $res["msg"]);
		}
	}
	public function mail_change_binding()
	{
		$validate = \think\Validate::make(["mail" => "require", "code" => "require"], ["mail.require" => "邮箱 不能为空！", "code.require" => "验证码 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		list($verify_code, $user) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, new \app\api\common\entity\MemberAppUserVerify());
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $user);
		}
		$code_log = \think\Db::name("verification_code_log")->where([["account", "=", $this->input["mail"]], ["mode", "=", \app\common\model\VerificationLog::Mode_Mail], ["type", "=", \app\common\model\VerificationLog::MailLog_MemberUserBindingMail], ["other", "=", $user["id"]]])->order("id", "desc")->find();
		if (empty($code_log) || $code_log["code"] != $this->input["code"]) {
			$this->response(10277, "验证码错误");
		}
		if (\time() > $code_log["expire"]) {
			$this->response(10278, "验证码过期");
		}
		if ($code_log["status"] == 1) {
			$this->response(10279, "验证码已失效");
		}
		\think\Db::name("verification_code_log")->where(["id" => $code_log["id"]])->update(["status" => 1]);
		try {
			\think\Db::startTrans();
			$row = \think\Db::name("app_member_user")->where(["mail" => $this->input["mail"], "appid" => $user["appid"]])->find();
			if (!empty($row) && $row["id"] != $user["id"]) {
				$this->response(10280, "该邮箱已被其他用户绑定");
			}
			\think\Db::name("app_member_user")->where(["id" => $user["id"]])->update(["mail" => $this->input["mail"]]);
			\think\Db::commit();
			$this->response(Code::success, "绑定成功");
		} catch (\Exception $e) {
			\think\Db::rollback();
			$this->response(Code::error, "失败：" . $e->getMessage());
		}
	}
	public function mail_unbinding()
	{
		$validate = \think\Validate::make(["code" => "require"], ["code.require" => "验证码 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		list($verify_code, $user) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, new \app\api\common\entity\MemberAppUserVerify());
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $user);
		}
		if (!$user["phone"]) {
			$this->response(10281, "账号未绑定邮箱无需解绑");
		}
		$code_log = \think\Db::name("verification_code_log")->where([["account", "=", $user["mail"]], ["mode", "=", \app\common\model\VerificationLog::Mode_Mail], ["type", "=", \app\common\model\VerificationLog::MailLog_MemberUserUnbindingMail], ["other", "=", $user["id"]]])->order("id", "desc")->find();
		if (empty($code_log) || $code_log["code"] != $this->input["code"]) {
			$this->response(10282, "验证码错误");
		}
		if (\time() > $code_log["expire"]) {
			$this->response(10283, "验证码过期");
		}
		if ($code_log["status"] == 1) {
			$this->response(10284, "验证码已失效");
		}
		\think\Db::name("verification_code_log")->where(["id" => $code_log["id"]])->update(["status" => 1]);
		\think\Db::name("app_member_user")->where(["id" => $user["id"]])->update(["mail" => ""]);
		$this->response(Code::success, "解绑成功");
	}
	public function get_reset_password_mail_code()
	{
		$validate = \think\Validate::make(["mail" => "require"], ["mail.require" => "邮箱 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		$user = \think\Db::name("app_member_user")->where(["appid" => $this->project["id"], "mail" => $this->input["mail"]])->find();
		if (empty($user)) {
			$this->response(10285, "您的邮箱未注册或绑定用户账号");
		}
		$res = \app\common\Mail::get_verification_code(json_decode($this->project["mail_config"], true), $user["mail"], "【{$this->project["name"]}】 - 邮箱验证重置密码", ["type" => \app\common\model\VerificationLog::MailLog_MemberUserResetPassword, "other" => $user["id"]]);
		if ($res["code"] == 10000) {
			$this->response(Code::success, $res["msg"]);
		} else {
			$this->response($res["code"], $res["msg"]);
		}
	}
	public function mail_verify_reset_password()
	{
		$validate = \think\Validate::make(["mail" => "require", "code" => "require", "new_password" => "require"], ["mail.require" => "邮箱 不能为空！", "code.require" => "验证码 不能为空！", "new_password.require" => "新密码 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		\think\Db::startTrans();
		try {
			$code_log = \think\Db::name("verification_code_log")->where([["account", "=", $this->input["mail"]], ["mode", "=", \app\common\model\VerificationLog::Mode_Mail], ["type", "=", \app\common\model\VerificationLog::MailLog_MemberUserResetPassword], ["other", "=", ""]])->order("id", "desc")->find();
			if (empty($code_log) || $code_log["code"] != $this->input["code"]) {
				$this->response(10286, "验证码错误");
			}
			if (\time() > $code_log["expire"]) {
				$this->response(10287, "验证码过期");
			}
			if ($code_log["status"] == 1) {
				$this->response(10288, "验证码已失效");
			}
			\think\Db::name("verification_code_log")->where(["id" => $code_log["id"]])->update(["status" => 1]);
			$user = \think\Db::name("app_member_user")->where(["appid" => $this->project["id"], "mail" => $this->input["mail"]])->find();
			if (empty($user)) {
				$this->response(10289, "您的邮箱未注册或绑定用户账号");
			}
			memberUserPasswordChange($user, $this->input["new_password"]);
			\think\Db::commit();
			$this->response(Code::success, "重置成功");
		} catch (\Exception $e) {
			\think\Db::rollback();
			$this->response(Code::error, $e->getMessage());
		}
	}
}